#include "stdafx.h"

#include "hwingraphics.h"
#include "hwincontrol.h"

#pragma comment(lib,"D2d1")
#pragma comment(lib,"Dwrite")


namespace harlinn
{
    namespace windows
    {
        namespace graphics
        {
            
            // ================================================================
            // Resource
            // ================================================================
            HWIN_EXPORT Factory Resource::GetFactory( )
            {
                InterfaceType* pInterface = GetInterface();
                ID2D1Factory *pFactory = nullptr;
                pInterface->GetFactory(&pFactory);
                if(pFactory)
                {
                    return Factory(pFactory);
                }
                return Factory();
            }

            // ================================================================
            // Bitmap
            // ================================================================
            HWIN_EXPORT D2D1_SIZE_F Bitmap::GetSize( ) const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetSize( );
            }

            HWIN_EXPORT D2D1_SIZE_U Bitmap::GetPixelSize( ) const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetPixelSize( );
            }
            HWIN_EXPORT D2D1_PIXEL_FORMAT Bitmap::GetPixelFormat( ) const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetPixelFormat( );
            }
            HWIN_EXPORT const Bitmap& Bitmap::GetDpi(FLOAT *dpiX, FLOAT *dpiY ) const
            {
                CheckPointerNotNull(dpiX);
                CheckPointerNotNull(dpiY);
                InterfaceType* pInterface = GetInterface();
                pInterface->GetDpi(dpiX, dpiY );
                return *this;
            }
            HWIN_EXPORT Bitmap& Bitmap::CopyFromBitmap(const D2D1_POINT_2U *destPoint, ID2D1Bitmap *bitmap,const D2D1_RECT_U *srcRect )
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CopyFromBitmap(destPoint, bitmap,srcRect );
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT Bitmap& Bitmap::CopyFromRenderTarget(const D2D1_POINT_2U *destPoint, ID2D1RenderTarget *renderTarget,const D2D1_RECT_U *srcRect )
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CopyFromRenderTarget(destPoint, renderTarget,srcRect );
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT Bitmap& Bitmap::CopyFromMemory(const D2D1_RECT_U *dstRect,const void *srcData,UINT32 pitch )
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CopyFromMemory(dstRect,srcData,pitch );
                CheckHRESULT(hr);
                return *this;
            }

            // ================================================================
            // GradientStopCollection
            // ================================================================
            HWIN_EXPORT UINT32 GradientStopCollection::GetGradientStopCount() const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetGradientStopCount();
            }
            HWIN_EXPORT const GradientStopCollection& GradientStopCollection::GetGradientStops(D2D1_GRADIENT_STOP *gradientStops,UINT32 gradientStopsCount ) const
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->GetGradientStops(gradientStops,gradientStopsCount );
                return *this;
            }
            HWIN_EXPORT D2D1_GAMMA GradientStopCollection::GetColorInterpolationGamma() const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetColorInterpolationGamma();
            }
            HWIN_EXPORT D2D1_EXTEND_MODE GradientStopCollection::GetExtendMode() const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetExtendMode();
            }

            // ================================================================
            // Brush
            // ================================================================
            HWIN_EXPORT Brush& Brush::SetOpacity(FLOAT opacity )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->SetOpacity(opacity);
                return *this;
            }
    
            HWIN_EXPORT Brush& Brush::SetTransform(const D2D1_MATRIX_3X2_F *transform )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->SetTransform(transform );
                return *this;
            }

            HWIN_EXPORT FLOAT Brush::GetOpacity() const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetOpacity( );
            }

            HWIN_EXPORT const Brush& Brush::GetTransform(D2D1_MATRIX_3X2_F *transform ) const
            {
                CheckPointerNotNull(transform);
                InterfaceType* pInterface = GetInterface();
                pInterface->GetTransform( transform );
                return *this;
            }

            // ================================================================
            // BitmapBrush
            // ================================================================
            HWIN_EXPORT BitmapBrush& BitmapBrush::SetExtendModeX(D2D1_EXTEND_MODE extendModeX )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->SetExtendModeX( extendModeX );
                return *this;
            }
    
            HWIN_EXPORT BitmapBrush& BitmapBrush::SetExtendModeY(D2D1_EXTEND_MODE extendModeY )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->SetExtendModeY(extendModeY );
                return *this;
            }
    
            HWIN_EXPORT BitmapBrush& BitmapBrush::SetInterpolationMode(D2D1_BITMAP_INTERPOLATION_MODE interpolationMode )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->SetInterpolationMode( interpolationMode );
                return *this;
            }

            HWIN_EXPORT BitmapBrush& BitmapBrush::SetBitmap(ID2D1Bitmap *bitmap )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->SetBitmap( bitmap );
                return *this;
            }

            HWIN_EXPORT D2D1_EXTEND_MODE BitmapBrush::GetExtendModeX() const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetExtendModeX( );
            }
            HWIN_EXPORT D2D1_EXTEND_MODE BitmapBrush::GetExtendModeY() const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetExtendModeY( );
            }
            HWIN_EXPORT D2D1_BITMAP_INTERPOLATION_MODE BitmapBrush::GetInterpolationMode() const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetInterpolationMode( );
            }

            HWIN_EXPORT Bitmap BitmapBrush::GetBitmap( ) const
            {
                ID2D1Bitmap* pBitmap = nullptr;
                InterfaceType* pInterface = GetInterface();
                pInterface->GetBitmap( &pBitmap );
                Bitmap result(pBitmap);
                return result;
            }

            // ================================================================
            // SolidColorBrush
            // ================================================================
            HWIN_EXPORT SolidColorBrush& SolidColorBrush::SetColor(const D2D1_COLOR_F *color )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->SetColor(color);
                return *this;
            }
    
            HWIN_EXPORT D2D1_COLOR_F SolidColorBrush::GetColor() const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetColor( );
            }


            // ================================================================
            // LinearGradientBrush
            // ================================================================
            HWIN_EXPORT LinearGradientBrush& LinearGradientBrush::SetStartPoint(D2D1_POINT_2F startPoint )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->SetStartPoint( startPoint );
                return *this;
            }

            HWIN_EXPORT LinearGradientBrush& LinearGradientBrush::SetEndPoint(D2D1_POINT_2F endPoint )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->SetEndPoint( endPoint );
                return *this;
            }

            HWIN_EXPORT D2D1_POINT_2F LinearGradientBrush::GetStartPoint() const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetStartPoint( );
            }

            HWIN_EXPORT D2D1_POINT_2F LinearGradientBrush::GetEndPoint() const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetEndPoint( );
            }

            HWIN_EXPORT GradientStopCollection LinearGradientBrush::GetGradientStopCollection(  ) const
            {
                ID2D1GradientStopCollection* pGradientStopCollection = nullptr;
                InterfaceType* pInterface = GetInterface();
                pInterface->GetGradientStopCollection( &pGradientStopCollection );
                GradientStopCollection result(pGradientStopCollection);
                return result;
            }

            // ================================================================
            // RadialGradientBrush
            // ================================================================
            HWIN_EXPORT RadialGradientBrush& RadialGradientBrush::SetCenter(D2D1_POINT_2F center )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->SetCenter( center );
                return *this;
            }

            HWIN_EXPORT RadialGradientBrush& RadialGradientBrush::SetGradientOriginOffset(D2D1_POINT_2F gradientOriginOffset )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->SetGradientOriginOffset(gradientOriginOffset );
                return *this;
            }

            HWIN_EXPORT RadialGradientBrush& RadialGradientBrush::SetRadiusX(FLOAT radiusX )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->SetRadiusX( radiusX );
                return *this;
            }

            HWIN_EXPORT RadialGradientBrush& RadialGradientBrush::SetRadiusY(FLOAT radiusY )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->SetRadiusY( radiusY );
                return *this;
            }

            HWIN_EXPORT D2D1_POINT_2F RadialGradientBrush::GetCenter() const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetCenter();
            }

            HWIN_EXPORT D2D1_POINT_2F RadialGradientBrush::GetGradientOriginOffset() const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetGradientOriginOffset();
            }

            HWIN_EXPORT FLOAT RadialGradientBrush::GetRadiusX() const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetRadiusX();
            }

            HWIN_EXPORT FLOAT RadialGradientBrush::GetRadiusY() const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetRadiusY();
            }

            HWIN_EXPORT GradientStopCollection RadialGradientBrush::GetGradientStopCollection( ) const
            {
                ID2D1GradientStopCollection* pGradientStopCollection = nullptr;
                InterfaceType* pInterface = GetInterface();
                pInterface->GetGradientStopCollection( &pGradientStopCollection );
                GradientStopCollection result(pGradientStopCollection);
                return result;
            }


            // ================================================================
            // StrokeStyle
            // ================================================================
            HWIN_EXPORT D2D1_CAP_STYLE StrokeStyle::GetStartCap() const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetStartCap();
            }

            HWIN_EXPORT D2D1_CAP_STYLE StrokeStyle::GetEndCap() const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetEndCap();
            }

            HWIN_EXPORT D2D1_CAP_STYLE StrokeStyle::GetDashCap() const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetDashCap();
            }

            HWIN_EXPORT FLOAT StrokeStyle::GetMiterLimit() const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetMiterLimit();
            }

            HWIN_EXPORT D2D1_LINE_JOIN StrokeStyle::GetLineJoin() const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetLineJoin();
            }

            HWIN_EXPORT FLOAT StrokeStyle::GetDashOffset() const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetDashOffset();
            }

            HWIN_EXPORT D2D1_DASH_STYLE StrokeStyle::GetDashStyle() const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetDashStyle();
            }

            HWIN_EXPORT UINT32 StrokeStyle::GetDashesCount() const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetDashesCount();
            }

            HWIN_EXPORT const StrokeStyle& StrokeStyle::GetDashes(FLOAT *dashes,UINT32 dashesCount ) const
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->GetDashes( dashes,dashesCount );
                return *this;
            }

            // ================================================================
            // Geometry
            // ================================================================
            HWIN_EXPORT const Geometry& Geometry::GetBounds(const D2D1_MATRIX_3X2_F *worldTransform, D2D1_RECT_F *bounds ) const
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetBounds(worldTransform, bounds );
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT const Geometry& Geometry::GetWidenedBounds(FLOAT strokeWidth,ID2D1StrokeStyle *strokeStyle,const D2D1_MATRIX_3X2_F *worldTransform,FLOAT flatteningTolerance,D2D1_RECT_F *bounds ) const
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetWidenedBounds(strokeWidth,strokeStyle,worldTransform,flatteningTolerance,bounds );
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT const Geometry& Geometry::StrokeContainsPoint(D2D1_POINT_2F point,FLOAT strokeWidth,ID2D1StrokeStyle *strokeStyle,const D2D1_MATRIX_3X2_F *worldTransform,FLOAT flatteningTolerance,BOOL *contains ) const
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->StrokeContainsPoint(point,strokeWidth,strokeStyle,worldTransform,flatteningTolerance, contains );
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT const Geometry& Geometry::FillContainsPoint(D2D1_POINT_2F point,const D2D1_MATRIX_3X2_F *worldTransform,FLOAT flatteningTolerance, BOOL *contains ) const
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->FillContainsPoint(point,worldTransform,flatteningTolerance, contains );
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT const Geometry& Geometry::CompareWithGeometry(ID2D1Geometry *inputGeometry,const D2D1_MATRIX_3X2_F *inputGeometryTransform,FLOAT flatteningTolerance, D2D1_GEOMETRY_RELATION *relation ) const
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CompareWithGeometry(inputGeometry,inputGeometryTransform,flatteningTolerance, relation );
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT const Geometry& Geometry::Simplify(D2D1_GEOMETRY_SIMPLIFICATION_OPTION simplificationOption,const D2D1_MATRIX_3X2_F *worldTransform,FLOAT flatteningTolerance, ID2D1SimplifiedGeometrySink *geometrySink ) const
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->Simplify(simplificationOption,worldTransform,flatteningTolerance, geometrySink );
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT const Geometry& Geometry::Tessellate(const D2D1_MATRIX_3X2_F *worldTransform,FLOAT flatteningTolerance, ID2D1TessellationSink *tessellationSink ) const
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->Tessellate(worldTransform,flatteningTolerance, tessellationSink );
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT const Geometry& Geometry::CombineWithGeometry( ID2D1Geometry *inputGeometry,D2D1_COMBINE_MODE combineMode,const D2D1_MATRIX_3X2_F *inputGeometryTransform,FLOAT flatteningTolerance, ID2D1SimplifiedGeometrySink *geometrySink ) const
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CombineWithGeometry( inputGeometry,combineMode,inputGeometryTransform,flatteningTolerance, geometrySink );
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT const Geometry& Geometry::Outline(const D2D1_MATRIX_3X2_F *worldTransform,FLOAT flatteningTolerance, ID2D1SimplifiedGeometrySink *geometrySink ) const
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->Outline(worldTransform,flatteningTolerance, geometrySink );
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT const Geometry& Geometry::ComputeArea(const D2D1_MATRIX_3X2_F *worldTransform,FLOAT flatteningTolerance, FLOAT *area ) const
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->ComputeArea(worldTransform,flatteningTolerance, area );
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT const Geometry& Geometry::ComputeLength(const D2D1_MATRIX_3X2_F *worldTransform,FLOAT flatteningTolerance, FLOAT *length ) const
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->ComputeLength(worldTransform,flatteningTolerance, length );
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT const Geometry& Geometry::ComputePointAtLength(FLOAT length,const D2D1_MATRIX_3X2_F *worldTransform,FLOAT flatteningTolerance, D2D1_POINT_2F *point, D2D1_POINT_2F *unitTangentVector ) const
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->ComputePointAtLength(length,worldTransform,flatteningTolerance, point, unitTangentVector );
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT const Geometry& Geometry::Widen(FLOAT strokeWidth,ID2D1StrokeStyle *strokeStyle,const D2D1_MATRIX_3X2_F *worldTransform,FLOAT flatteningTolerance, ID2D1SimplifiedGeometrySink *geometrySink ) const
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->Widen(strokeWidth,strokeStyle,worldTransform,flatteningTolerance, geometrySink );
                CheckHRESULT(hr);
                return *this;
            }


            // ================================================================
            // RectangleGeometry
            // ================================================================
            HWIN_EXPORT const RectangleGeometry& RectangleGeometry::GetRect( D2D1_RECT_F *rect ) const
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->GetRect( rect );
                return *this;
            }

            // ================================================================
            // RoundedRectangleGeometry
            // ================================================================
            HWIN_EXPORT const RoundedRectangleGeometry& RoundedRectangleGeometry::GetRoundedRect(D2D1_ROUNDED_RECT *roundedRect ) const
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->GetRoundedRect( roundedRect );
                return *this;
            }

            // ================================================================
            // EllipseGeometry
            // ================================================================
            HWIN_EXPORT const EllipseGeometry& EllipseGeometry::GetEllipse(D2D1_ELLIPSE *ellipse ) const
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->GetEllipse( ellipse );
                return *this;
            }

            // ================================================================
            // GeometryGroup
            // ================================================================
            HWIN_EXPORT D2D1_FILL_MODE GeometryGroup::GetFillMode() const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetFillMode( );
            }

            HWIN_EXPORT UINT32 GeometryGroup::GetSourceGeometryCount( ) const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetSourceGeometryCount( );
            }

            HWIN_EXPORT const GeometryGroup& GeometryGroup::GetSourceGeometries( ID2D1Geometry **geometries, UINT32 geometriesCount ) const
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->GetSourceGeometries( geometries, geometriesCount );
                return *this;
            }


            // ================================================================
            // TransformedGeometry
            // ================================================================

            HWIN_EXPORT const TransformedGeometry& TransformedGeometry::GetSourceGeometry( ID2D1Geometry **sourceGeometry ) const
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->GetSourceGeometry( sourceGeometry );
                return *this;
            }
    
            HWIN_EXPORT const TransformedGeometry& TransformedGeometry::GetTransform(D2D1_MATRIX_3X2_F *transform ) const
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->GetTransform( transform );
                return *this;
            }

            // ================================================================
            // SimplifiedGeometrySink
            // ================================================================
            HWIN_EXPORT SimplifiedGeometrySink& SimplifiedGeometrySink::SetFillMode(D2D1_FILL_MODE fillMode )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->SetFillMode( fillMode );
                return *this;
            }

            HWIN_EXPORT SimplifiedGeometrySink& SimplifiedGeometrySink::SetSegmentFlags(D2D1_PATH_SEGMENT vertexFlags )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->SetSegmentFlags( vertexFlags );
                return *this;
            }

    
            HWIN_EXPORT SimplifiedGeometrySink& SimplifiedGeometrySink::BeginFigure(D2D1_POINT_2F startPoint,D2D1_FIGURE_BEGIN figureBegin )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->BeginFigure(startPoint, figureBegin );
                return *this;
            }

            HWIN_EXPORT SimplifiedGeometrySink& SimplifiedGeometrySink::AddLines(const D2D1_POINT_2F *points,UINT32 pointsCount )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->AddLines(points, pointsCount );
                return *this;
            }

            HWIN_EXPORT SimplifiedGeometrySink& SimplifiedGeometrySink::AddBeziers(const D2D1_BEZIER_SEGMENT *beziers,UINT32 beziersCount )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->AddBeziers(beziers, beziersCount );
                return *this;
            }

            HWIN_EXPORT SimplifiedGeometrySink& SimplifiedGeometrySink::EndFigure(D2D1_FIGURE_END figureEnd )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->EndFigure( figureEnd );
                return *this;
            }

            HWIN_EXPORT SimplifiedGeometrySink& SimplifiedGeometrySink::Close()
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->Close();
                CheckHRESULT(hr);
                return *this;
            }

            // ================================================================
            // GeometrySink
            // ================================================================
            HWIN_EXPORT GeometrySink& GeometrySink::AddLine(D2D1_POINT_2F point)
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->AddLine(point);
                return *this;
            }

            HWIN_EXPORT GeometrySink& GeometrySink::AddBezier(const D2D1_BEZIER_SEGMENT *bezier)
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->AddBezier(bezier);
                return *this;
            }

            HWIN_EXPORT GeometrySink& GeometrySink::AddQuadraticBezier(const D2D1_QUADRATIC_BEZIER_SEGMENT *bezier )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->AddQuadraticBezier( bezier );
                return *this;
            }

            HWIN_EXPORT GeometrySink& GeometrySink::AddQuadraticBeziers(const D2D1_QUADRATIC_BEZIER_SEGMENT *beziers,UINT32 beziersCount )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->AddQuadraticBeziers(beziers,beziersCount );
                return *this;
            }

            HWIN_EXPORT GeometrySink& GeometrySink::AddArc(const D2D1_ARC_SEGMENT *arc )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->AddArc( arc );
                return *this;
            }

            // ================================================================
            // TessellationSink
            // ================================================================
            HWIN_EXPORT TessellationSink& TessellationSink::AddTriangles(const D2D1_TRIANGLE *triangles, UINT32 trianglesCount )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->AddTriangles(triangles, trianglesCount );
                return *this;
            }

            HWIN_EXPORT TessellationSink& TessellationSink::Close()
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->Close();
                return *this;
            }

            // ================================================================
            // PathGeometry
            // ================================================================
            HWIN_EXPORT PathGeometry& PathGeometry::Open(ID2D1GeometrySink **geometrySink)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->Open(geometrySink);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT GeometrySink PathGeometry::Open( )
            {
                InterfaceType* pInterface = GetInterface();
                ID2D1GeometrySink* geometrySink;
                HRESULT hr = pInterface->Open(&geometrySink);
                CheckHRESULT(hr);
                GeometrySink result(geometrySink);
                return result;
            }

            HWIN_EXPORT const PathGeometry& PathGeometry::Stream(ID2D1GeometrySink *geometrySink) const
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->Stream(geometrySink);
                CheckHRESULT(hr);
                return *this;
            }
    
            HWIN_EXPORT const PathGeometry& PathGeometry::GetSegmentCount(UINT32 *count) const
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetSegmentCount(count);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT UINT32 PathGeometry::GetSegmentCount( ) const
            {
                InterfaceType* pInterface = GetInterface();
                UINT32 result = 0;
                HRESULT hr = pInterface->GetSegmentCount(&result);
                CheckHRESULT(hr);
                return result;
            }

            HWIN_EXPORT const PathGeometry& PathGeometry::GetFigureCount(UINT32 *count) const
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFigureCount(count);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT UINT32 PathGeometry::GetFigureCount( ) const
            {
                InterfaceType* pInterface = GetInterface();
                UINT32 result = 0;
                HRESULT hr = pInterface->GetFigureCount(&result);
                CheckHRESULT(hr);
                return result;
            }

            // ================================================================
            // Mesh
            // ================================================================
            HWIN_EXPORT Mesh& Mesh::Open(ID2D1TessellationSink **tessellationSink )
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->Open(tessellationSink);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT TessellationSink Mesh::Open( )
            {
                InterfaceType* pInterface = GetInterface();
                ID2D1TessellationSink* pTessellationSink;
                HRESULT hr = pInterface->Open(&pTessellationSink);
                CheckHRESULT(hr);
                TessellationSink result(pTessellationSink);
                return result;
            }

            // ================================================================
            // Layer
            // ================================================================
            HWIN_EXPORT D2D1_SIZE_F Layer::GetSize() const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetSize();
            }


            // ================================================================
            // DrawingStateBlock
            // ================================================================
            HWIN_EXPORT const DrawingStateBlock& DrawingStateBlock::GetDescription(D2D1_DRAWING_STATE_DESCRIPTION *stateDescription ) const
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->GetDescription( stateDescription );
                return *this;
            }

            HWIN_EXPORT DrawingStateBlock& DrawingStateBlock::SetDescription(const D2D1_DRAWING_STATE_DESCRIPTION *stateDescription )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->SetDescription( stateDescription );
                return *this;
            }
            HWIN_EXPORT DrawingStateBlock& DrawingStateBlock::SetTextRenderingParams(IDWriteRenderingParams *textRenderingParams )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->SetTextRenderingParams( textRenderingParams );
                return *this;
            }

            HWIN_EXPORT const DrawingStateBlock& DrawingStateBlock::GetTextRenderingParams(IDWriteRenderingParams **textRenderingParams ) const
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->GetTextRenderingParams( textRenderingParams );
                return *this;
            }

            // ================================================================
            // RenderTarget
            // ================================================================
            HWIN_EXPORT Bitmap RenderTarget::CreateBitmap(D2D1_SIZE_U size, const void *srcData, UINT32 pitch, const D2D1_BITMAP_PROPERTIES* bitmapProperties)
            {
                CheckPointerNotNull(bitmapProperties);
                ID2D1Bitmap *pBitmap = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateBitmap(size, srcData, pitch, bitmapProperties,&pBitmap);
                CheckHRESULT(hr);

                Bitmap result(pBitmap);
                return result;
            }

            HWIN_EXPORT Bitmap RenderTarget::CreateBitmap(D2D1_SIZE_U size, const void *srcData, UINT32 pitch, const D2D1_BITMAP_PROPERTIES& bitmapProperties)
            {
                ID2D1Bitmap *pBitmap = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateBitmap(size, srcData, pitch, &bitmapProperties,&pBitmap);
                CheckHRESULT(hr);

                Bitmap result(pBitmap);
                return result;
            }


            HWIN_EXPORT Bitmap RenderTarget::CreateBitmap(D2D1_SIZE_U size, const D2D1_BITMAP_PROPERTIES* bitmapProperties)
            {
                CheckPointerNotNull(bitmapProperties);

                ID2D1Bitmap *pBitmap = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateBitmap(size, nullptr, 0, bitmapProperties,&pBitmap);
                CheckHRESULT(hr);

                Bitmap result(pBitmap);
                return result;
            }

            HWIN_EXPORT Bitmap RenderTarget::CreateBitmap(D2D1_SIZE_U size, const D2D1_BITMAP_PROPERTIES& bitmapProperties)
            {
                ID2D1Bitmap *pBitmap = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateBitmap(size, nullptr, 0, &bitmapProperties,&pBitmap);
                CheckHRESULT(hr);

                Bitmap result(pBitmap);
                return result;
            }


            HWIN_EXPORT Bitmap RenderTarget::CreateBitmapFromWicBitmap(IWICBitmapSource *wicBitmapSource,const D2D1_BITMAP_PROPERTIES *bitmapProperties)
            {
                CheckPointerNotNull(wicBitmapSource);
                CheckPointerNotNull(bitmapProperties);

                ID2D1Bitmap *pBitmap = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateBitmapFromWicBitmap(wicBitmapSource, bitmapProperties,&pBitmap);
                CheckHRESULT(hr);

                Bitmap result(pBitmap);
                return result;
            }

            HWIN_EXPORT Bitmap RenderTarget::CreateBitmapFromWicBitmap(IWICBitmapSource *wicBitmapSource,const D2D1_BITMAP_PROPERTIES& bitmapProperties)
            {
                CheckPointerNotNull(wicBitmapSource);

                ID2D1Bitmap *pBitmap = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateBitmapFromWicBitmap(wicBitmapSource, &bitmapProperties,&pBitmap);
                CheckHRESULT(hr);

                Bitmap result(pBitmap);
                return result;
            }


            HWIN_EXPORT Bitmap RenderTarget::CreateBitmapFromWicBitmap( IWICBitmapSource *wicBitmapSource )
            {
                CheckPointerNotNull(wicBitmapSource);

                ID2D1Bitmap *pBitmap = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateBitmapFromWicBitmap(wicBitmapSource, nullptr,&pBitmap);
                CheckHRESULT(hr);

                Bitmap result(pBitmap);
                return result;
            }


            HWIN_EXPORT Bitmap RenderTarget::CreateSharedBitmap(REFIID riid,void *data,const D2D1_BITMAP_PROPERTIES* bitmapProperties)
            {
                CheckPointerNotNull(data);
                CheckPointerNotNull(bitmapProperties);

                ID2D1Bitmap *pBitmap = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateSharedBitmap(riid,data,bitmapProperties,&pBitmap);
                CheckHRESULT(hr);

                Bitmap result(pBitmap);
                return result;
            }
            HWIN_EXPORT Bitmap RenderTarget::CreateSharedBitmap(REFIID riid,void *data,const D2D1_BITMAP_PROPERTIES& bitmapProperties)
            {
                CheckPointerNotNull(data);

                ID2D1Bitmap *pBitmap = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateSharedBitmap(riid,data,&bitmapProperties,&pBitmap);
                CheckHRESULT(hr);

                Bitmap result(pBitmap);
                return result;
            }

            HWIN_EXPORT BitmapBrush RenderTarget::CreateBitmapBrush(ID2D1Bitmap *bitmap,const D2D1_BITMAP_BRUSH_PROPERTIES *bitmapBrushProperties,const D2D1_BRUSH_PROPERTIES *brushProperties)
            {
                CheckPointerNotNull(bitmap);

                ID2D1BitmapBrush *pBitmapBrush = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateBitmapBrush(bitmap,bitmapBrushProperties,brushProperties,&pBitmapBrush);
                CheckHRESULT(hr);

                BitmapBrush result(pBitmapBrush);
                return result;
            }

            HWIN_EXPORT BitmapBrush RenderTarget::CreateBitmapBrush(ID2D1Bitmap *bitmap,const D2D1_BITMAP_BRUSH_PROPERTIES& bitmapBrushProperties,const D2D1_BRUSH_PROPERTIES* brushProperties)
            {
                CheckPointerNotNull(bitmap);

                ID2D1BitmapBrush *pBitmapBrush = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateBitmapBrush(bitmap,&bitmapBrushProperties,brushProperties,&pBitmapBrush);
                CheckHRESULT(hr);

                BitmapBrush result(pBitmapBrush);
                return result;
            }

            HWIN_EXPORT BitmapBrush RenderTarget::CreateBitmapBrush(ID2D1Bitmap *bitmap,const D2D1_BITMAP_BRUSH_PROPERTIES* bitmapBrushProperties,const D2D1_BRUSH_PROPERTIES& brushProperties)
            {
                CheckPointerNotNull(bitmap);

                ID2D1BitmapBrush *pBitmapBrush = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateBitmapBrush(bitmap,bitmapBrushProperties,&brushProperties,&pBitmapBrush);
                CheckHRESULT(hr);

                BitmapBrush result(pBitmapBrush);
                return result;
            }

            HWIN_EXPORT BitmapBrush RenderTarget::CreateBitmapBrush(ID2D1Bitmap *bitmap,const D2D1_BITMAP_BRUSH_PROPERTIES& bitmapBrushProperties,const D2D1_BRUSH_PROPERTIES& brushProperties)
            {
                CheckPointerNotNull(bitmap);

                ID2D1BitmapBrush *pBitmapBrush = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateBitmapBrush(bitmap,&bitmapBrushProperties,&brushProperties,&pBitmapBrush);
                CheckHRESULT(hr);

                BitmapBrush result(pBitmapBrush);
                return result;
            }

            HWIN_EXPORT BitmapBrush RenderTarget::CreateBitmapBrush(ID2D1Bitmap *bitmap,const D2D1_BRUSH_PROPERTIES* brushProperties)
            {
                CheckPointerNotNull(bitmap);

                ID2D1BitmapBrush *pBitmapBrush = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateBitmapBrush(bitmap,nullptr,brushProperties,&pBitmapBrush);
                CheckHRESULT(hr);

                BitmapBrush result(pBitmapBrush);
                return result;
            }

            HWIN_EXPORT BitmapBrush RenderTarget::CreateBitmapBrush(ID2D1Bitmap *bitmap,const D2D1_BRUSH_PROPERTIES& brushProperties)
            {
                CheckPointerNotNull(bitmap);

                ID2D1BitmapBrush *pBitmapBrush = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateBitmapBrush(bitmap,nullptr,&brushProperties,&pBitmapBrush);
                CheckHRESULT(hr);

                BitmapBrush result(pBitmapBrush);
                return result;
            }

            HWIN_EXPORT BitmapBrush RenderTarget::CreateBitmapBrush(ID2D1Bitmap *bitmap,const D2D1_BITMAP_BRUSH_PROPERTIES* bitmapBrushProperties)
            {
                CheckPointerNotNull(bitmap);

                ID2D1BitmapBrush *pBitmapBrush = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateBitmapBrush(bitmap,bitmapBrushProperties,nullptr,&pBitmapBrush);
                CheckHRESULT(hr);

                BitmapBrush result(pBitmapBrush);
                return result;
            }

            HWIN_EXPORT BitmapBrush RenderTarget::CreateBitmapBrush(ID2D1Bitmap *bitmap,const D2D1_BITMAP_BRUSH_PROPERTIES& bitmapBrushProperties)
            {
                CheckPointerNotNull(bitmap);

                ID2D1BitmapBrush *pBitmapBrush = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateBitmapBrush(bitmap,&bitmapBrushProperties,nullptr,&pBitmapBrush);
                CheckHRESULT(hr);

                BitmapBrush result(pBitmapBrush);
                return result;
            }

            HWIN_EXPORT BitmapBrush RenderTarget::CreateBitmapBrush(ID2D1Bitmap *bitmap )
            {
                CheckPointerNotNull(bitmap);

                ID2D1BitmapBrush *pBitmapBrush = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateBitmapBrush(bitmap,nullptr,nullptr,&pBitmapBrush);
                CheckHRESULT(hr);

                BitmapBrush result(pBitmapBrush);
                return result;
            }

            HWIN_EXPORT SolidColorBrush RenderTarget::CreateSolidColorBrush(const D2D1_COLOR_F *color,const D2D1_BRUSH_PROPERTIES *brushProperties)
            {
                CheckPointerNotNull(color);

                ID2D1SolidColorBrush *pSolidColorBrush = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateSolidColorBrush(color,brushProperties,&pSolidColorBrush);
                CheckHRESULT(hr);

                SolidColorBrush result(pSolidColorBrush);
                return result;
            }

            HWIN_EXPORT SolidColorBrush RenderTarget::CreateSolidColorBrush(const D2D1_COLOR_F& color,const D2D1_BRUSH_PROPERTIES* brushProperties)
            {

                ID2D1SolidColorBrush *pSolidColorBrush = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateSolidColorBrush(&color,brushProperties,&pSolidColorBrush);
                CheckHRESULT(hr);

                SolidColorBrush result(pSolidColorBrush);
                return result;
            }

            HWIN_EXPORT SolidColorBrush RenderTarget::CreateSolidColorBrush(const D2D1_COLOR_F* color,const D2D1_BRUSH_PROPERTIES& brushProperties)
            {
                CheckPointerNotNull(color);

                ID2D1SolidColorBrush *pSolidColorBrush = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateSolidColorBrush(color,&brushProperties,&pSolidColorBrush);
                CheckHRESULT(hr);

                SolidColorBrush result(pSolidColorBrush);
                return result;
            }

            HWIN_EXPORT SolidColorBrush RenderTarget::CreateSolidColorBrush(const D2D1_COLOR_F& color,const D2D1_BRUSH_PROPERTIES& brushProperties)
            {
                

                ID2D1SolidColorBrush *pSolidColorBrush = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateSolidColorBrush(&color,&brushProperties,&pSolidColorBrush);
                CheckHRESULT(hr);

                SolidColorBrush result(pSolidColorBrush);
                return result;
            }

            HWIN_EXPORT SolidColorBrush RenderTarget::CreateSolidColorBrush(const D2D1_COLOR_F* color)
            {
                CheckPointerNotNull(color);

                ID2D1SolidColorBrush *pSolidColorBrush = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateSolidColorBrush(color,nullptr,&pSolidColorBrush);
                CheckHRESULT(hr);

                SolidColorBrush result(pSolidColorBrush);
                return result;
            }

            HWIN_EXPORT SolidColorBrush RenderTarget::CreateSolidColorBrush(const D2D1_COLOR_F& color)
            {

                ID2D1SolidColorBrush *pSolidColorBrush = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateSolidColorBrush(&color,nullptr,&pSolidColorBrush);
                CheckHRESULT(hr);

                SolidColorBrush result(pSolidColorBrush);
                return result;
            }

            HWIN_EXPORT GradientStopCollection RenderTarget::CreateGradientStopCollection(const D2D1_GRADIENT_STOP *gradientStops,
                    UINT32 gradientStopsCount,
                    D2D1_GAMMA colorInterpolationGamma, 
                    D2D1_EXTEND_MODE extendMode)
            {
                CheckPointerNotNull(gradientStops);

                ID2D1GradientStopCollection *pGradientStopCollection = nullptr;
                InterfaceType* pInterface = GetInterface();


                HRESULT hr = pInterface->CreateGradientStopCollection(gradientStops,gradientStopsCount,colorInterpolationGamma, extendMode,&pGradientStopCollection);
                CheckHRESULT(hr);

                GradientStopCollection result(pGradientStopCollection);
                return result;

            }


            HWIN_EXPORT GradientStopCollection RenderTarget::CreateGradientStopCollection(const D2D1_GRADIENT_STOP *gradientStops, UINT32 gradientStopsCount)
            {
                CheckPointerNotNull(gradientStops);

                ID2D1GradientStopCollection *pGradientStopCollection = nullptr;
                InterfaceType* pInterface = GetInterface();


                HRESULT hr = pInterface->CreateGradientStopCollection(gradientStops,gradientStopsCount,D2D1_GAMMA_2_2, D2D1_EXTEND_MODE_CLAMP,&pGradientStopCollection);
                CheckHRESULT(hr);

                GradientStopCollection result(pGradientStopCollection);
                return result;
            }

            HWIN_EXPORT LinearGradientBrush RenderTarget::CreateLinearGradientBrush(const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES* linearGradientBrushProperties, const D2D1_BRUSH_PROPERTIES* brushProperties, ID2D1GradientStopCollection* gradientStopCollection)
            {
                CheckPointerNotNull(linearGradientBrushProperties);
                CheckPointerNotNull(gradientStopCollection);

                ID2D1LinearGradientBrush *pLinearGradientBrush = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateLinearGradientBrush(linearGradientBrushProperties, brushProperties, gradientStopCollection,&pLinearGradientBrush);
                CheckHRESULT(hr);

                LinearGradientBrush result(pLinearGradientBrush);
                return result;
            }


            HWIN_EXPORT LinearGradientBrush RenderTarget::CreateLinearGradientBrush(const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES& linearGradientBrushProperties, const D2D1_BRUSH_PROPERTIES* brushProperties, ID2D1GradientStopCollection* gradientStopCollection)
            {
                CheckPointerNotNull(gradientStopCollection);

                ID2D1LinearGradientBrush *pLinearGradientBrush = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateLinearGradientBrush(&linearGradientBrushProperties, brushProperties, gradientStopCollection,&pLinearGradientBrush);
                CheckHRESULT(hr);

                LinearGradientBrush result(pLinearGradientBrush);
                return result;
            }

            HWIN_EXPORT LinearGradientBrush RenderTarget::CreateLinearGradientBrush(const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES* linearGradientBrushProperties, const D2D1_BRUSH_PROPERTIES& brushProperties, ID2D1GradientStopCollection* gradientStopCollection)
            {
                CheckPointerNotNull(linearGradientBrushProperties);
                CheckPointerNotNull(gradientStopCollection);

                ID2D1LinearGradientBrush *pLinearGradientBrush = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateLinearGradientBrush(linearGradientBrushProperties, &brushProperties, gradientStopCollection,&pLinearGradientBrush);
                CheckHRESULT(hr);

                LinearGradientBrush result(pLinearGradientBrush);
                return result;
            }

            HWIN_EXPORT LinearGradientBrush RenderTarget::CreateLinearGradientBrush(const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES& linearGradientBrushProperties, const D2D1_BRUSH_PROPERTIES& brushProperties, ID2D1GradientStopCollection* gradientStopCollection)
            {
                CheckPointerNotNull(gradientStopCollection);

                ID2D1LinearGradientBrush *pLinearGradientBrush = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateLinearGradientBrush(&linearGradientBrushProperties, &brushProperties, gradientStopCollection,&pLinearGradientBrush);
                CheckHRESULT(hr);

                LinearGradientBrush result(pLinearGradientBrush);
                return result;
            }


            HWIN_EXPORT LinearGradientBrush RenderTarget::CreateLinearGradientBrush(const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES* linearGradientBrushProperties, ID2D1GradientStopCollection* gradientStopCollection)
            {
                CheckPointerNotNull(linearGradientBrushProperties);
                CheckPointerNotNull(gradientStopCollection);

                ID2D1LinearGradientBrush *pLinearGradientBrush = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateLinearGradientBrush(linearGradientBrushProperties, nullptr, gradientStopCollection,&pLinearGradientBrush);
                CheckHRESULT(hr);

                LinearGradientBrush result(pLinearGradientBrush);
                return result;
            }

            HWIN_EXPORT LinearGradientBrush RenderTarget::CreateLinearGradientBrush(const D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES& linearGradientBrushProperties, ID2D1GradientStopCollection* gradientStopCollection)
            {
                CheckPointerNotNull(gradientStopCollection);

                ID2D1LinearGradientBrush *pLinearGradientBrush = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateLinearGradientBrush(&linearGradientBrushProperties, nullptr, gradientStopCollection,&pLinearGradientBrush);
                CheckHRESULT(hr);

                LinearGradientBrush result(pLinearGradientBrush);
                return result;
            }

            HWIN_EXPORT LinearGradientBrush RenderTarget::CreateLinearGradientBrush(const D2D1_POINT_2F& startPoint, const D2D1_POINT_2F& endPoint, ID2D1GradientStopCollection* gradientStopCollection)
            {
                D2D1_LINEAR_GRADIENT_BRUSH_PROPERTIES linearGradientBrushProperties = {startPoint,endPoint};
                CheckPointerNotNull(gradientStopCollection);

                ID2D1LinearGradientBrush *pLinearGradientBrush = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateLinearGradientBrush(&linearGradientBrushProperties, nullptr, gradientStopCollection,&pLinearGradientBrush);
                CheckHRESULT(hr);

                LinearGradientBrush result(pLinearGradientBrush);
                return result;
            }


            HWIN_EXPORT RadialGradientBrush RenderTarget::CreateRadialGradientBrush(const D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES *radialGradientBrushProperties, const D2D1_BRUSH_PROPERTIES *brushProperties, ID2D1GradientStopCollection *gradientStopCollection)
            {
                CheckPointerNotNull(radialGradientBrushProperties);
                CheckPointerNotNull(gradientStopCollection);

                ID2D1RadialGradientBrush *pRadialGradientBrush = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateRadialGradientBrush(radialGradientBrushProperties, brushProperties, gradientStopCollection,&pRadialGradientBrush);
                CheckHRESULT(hr);

                RadialGradientBrush result(pRadialGradientBrush);
                return result;
            }


            HWIN_EXPORT RadialGradientBrush RenderTarget::CreateRadialGradientBrush(const D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES& radialGradientBrushProperties, const D2D1_BRUSH_PROPERTIES* brushProperties, ID2D1GradientStopCollection* gradientStopCollection)
            {
                CheckPointerNotNull(gradientStopCollection);

                ID2D1RadialGradientBrush *pRadialGradientBrush = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateRadialGradientBrush(&radialGradientBrushProperties, brushProperties, gradientStopCollection,&pRadialGradientBrush);
                CheckHRESULT(hr);

                RadialGradientBrush result(pRadialGradientBrush);
                return result;
            }

            HWIN_EXPORT RadialGradientBrush RenderTarget::CreateRadialGradientBrush(const D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES* radialGradientBrushProperties, const D2D1_BRUSH_PROPERTIES& brushProperties, ID2D1GradientStopCollection* gradientStopCollection)
            {
                CheckPointerNotNull(radialGradientBrushProperties);
                CheckPointerNotNull(gradientStopCollection);

                ID2D1RadialGradientBrush *pRadialGradientBrush = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateRadialGradientBrush(radialGradientBrushProperties, &brushProperties, gradientStopCollection,&pRadialGradientBrush);
                CheckHRESULT(hr);

                RadialGradientBrush result(pRadialGradientBrush);
                return result;
            }

            HWIN_EXPORT RadialGradientBrush RenderTarget::CreateRadialGradientBrush(const D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES& radialGradientBrushProperties, const D2D1_BRUSH_PROPERTIES& brushProperties, ID2D1GradientStopCollection* gradientStopCollection)
            {
                CheckPointerNotNull(gradientStopCollection);

                ID2D1RadialGradientBrush *pRadialGradientBrush = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateRadialGradientBrush(&radialGradientBrushProperties, &brushProperties, gradientStopCollection,&pRadialGradientBrush);
                CheckHRESULT(hr);

                RadialGradientBrush result(pRadialGradientBrush);
                return result;
            }

    
            HWIN_EXPORT RadialGradientBrush RenderTarget::CreateRadialGradientBrush(const D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES* radialGradientBrushProperties, ID2D1GradientStopCollection* gradientStopCollection)
            {
                CheckPointerNotNull(radialGradientBrushProperties);
                CheckPointerNotNull(gradientStopCollection);

                ID2D1RadialGradientBrush *pRadialGradientBrush = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateRadialGradientBrush(radialGradientBrushProperties, nullptr, gradientStopCollection,&pRadialGradientBrush);
                CheckHRESULT(hr);

                RadialGradientBrush result(pRadialGradientBrush);
                return result;
            }

            HWIN_EXPORT RadialGradientBrush RenderTarget::CreateRadialGradientBrush(const D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES& radialGradientBrushProperties, ID2D1GradientStopCollection* gradientStopCollection)
            {
                CheckPointerNotNull(gradientStopCollection);

                ID2D1RadialGradientBrush *pRadialGradientBrush = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateRadialGradientBrush(&radialGradientBrushProperties, nullptr, gradientStopCollection,&pRadialGradientBrush);
                CheckHRESULT(hr);

                RadialGradientBrush result(pRadialGradientBrush);
                return result;
            }


            HWIN_EXPORT RadialGradientBrush RenderTarget::CreateRadialGradientBrush(const D2D1_POINT_2F& center, const D2D1_POINT_2F& gradientOriginOffset, FLOAT radiusX, FLOAT radiusY, ID2D1GradientStopCollection* gradientStopCollection)
            {
                D2D1_RADIAL_GRADIENT_BRUSH_PROPERTIES radialGradientBrushProperties = {center, gradientOriginOffset, radiusX, radiusY};
                CheckPointerNotNull(gradientStopCollection);

                ID2D1RadialGradientBrush *pRadialGradientBrush = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateRadialGradientBrush(&radialGradientBrushProperties, nullptr, gradientStopCollection,&pRadialGradientBrush);
                CheckHRESULT(hr);

                RadialGradientBrush result(pRadialGradientBrush);
                return result;
            }


            HWIN_EXPORT BitmapRenderTarget RenderTarget::CreateCompatibleRenderTarget(const D2D1_SIZE_F *desiredSize, const D2D1_SIZE_U *desiredPixelSize, const D2D1_PIXEL_FORMAT *desiredFormat,D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options) 
            {
                ID2D1BitmapRenderTarget *pBitmapRenderTarget = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateCompatibleRenderTarget(desiredSize, desiredPixelSize, desiredFormat,options,&pBitmapRenderTarget);
                CheckHRESULT(hr);

                BitmapRenderTarget result(pBitmapRenderTarget);
                return result;
            }


            HWIN_EXPORT BitmapRenderTarget RenderTarget::CreateCompatibleRenderTarget(const D2D1_SIZE_F* desiredSize, const D2D1_SIZE_U* desiredPixelSize, const D2D1_PIXEL_FORMAT& desiredFormat, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options)
            {
                ID2D1BitmapRenderTarget *pBitmapRenderTarget = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateCompatibleRenderTarget(desiredSize, desiredPixelSize, &desiredFormat,options,&pBitmapRenderTarget);
                CheckHRESULT(hr);

                BitmapRenderTarget result(pBitmapRenderTarget);
                return result;
            }

            HWIN_EXPORT BitmapRenderTarget RenderTarget::CreateCompatibleRenderTarget(const D2D1_SIZE_F* desiredSize, const D2D1_SIZE_U& desiredPixelSize, const D2D1_PIXEL_FORMAT* desiredFormat, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options)
            {
                ID2D1BitmapRenderTarget *pBitmapRenderTarget = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateCompatibleRenderTarget(desiredSize, &desiredPixelSize, desiredFormat,options,&pBitmapRenderTarget);
                CheckHRESULT(hr);

                BitmapRenderTarget result(pBitmapRenderTarget);
                return result;
            }

            HWIN_EXPORT BitmapRenderTarget RenderTarget::CreateCompatibleRenderTarget(const D2D1_SIZE_F* desiredSize, const D2D1_SIZE_U& desiredPixelSize, const D2D1_PIXEL_FORMAT& desiredFormat, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options)
            {
                ID2D1BitmapRenderTarget *pBitmapRenderTarget = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateCompatibleRenderTarget(desiredSize, &desiredPixelSize, &desiredFormat,options,&pBitmapRenderTarget);
                CheckHRESULT(hr);

                BitmapRenderTarget result(pBitmapRenderTarget);
                return result;
            }

            HWIN_EXPORT BitmapRenderTarget RenderTarget::CreateCompatibleRenderTarget(const D2D1_SIZE_F& desiredSize, const D2D1_SIZE_U* desiredPixelSize, const D2D1_PIXEL_FORMAT* desiredFormat, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options)
            {
                ID2D1BitmapRenderTarget *pBitmapRenderTarget = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateCompatibleRenderTarget(&desiredSize, desiredPixelSize, desiredFormat,options,&pBitmapRenderTarget);
                CheckHRESULT(hr);

                BitmapRenderTarget result(pBitmapRenderTarget);
                return result;
            }

            HWIN_EXPORT BitmapRenderTarget RenderTarget::CreateCompatibleRenderTarget(const D2D1_SIZE_F& desiredSize, const D2D1_SIZE_U* desiredPixelSize, const D2D1_PIXEL_FORMAT& desiredFormat, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options)
            {
                ID2D1BitmapRenderTarget *pBitmapRenderTarget = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateCompatibleRenderTarget(&desiredSize, desiredPixelSize, &desiredFormat,options,&pBitmapRenderTarget);
                CheckHRESULT(hr);

                BitmapRenderTarget result(pBitmapRenderTarget);
                return result;
            }

            HWIN_EXPORT BitmapRenderTarget RenderTarget::CreateCompatibleRenderTarget(const D2D1_SIZE_F& desiredSize, const D2D1_SIZE_U& desiredPixelSize, const D2D1_PIXEL_FORMAT& desiredFormat, D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS options)
            {
                ID2D1BitmapRenderTarget *pBitmapRenderTarget = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateCompatibleRenderTarget(&desiredSize, &desiredPixelSize, &desiredFormat,options,&pBitmapRenderTarget);
                CheckHRESULT(hr);

                BitmapRenderTarget result(pBitmapRenderTarget);
                return result;
            }


            HWIN_EXPORT BitmapRenderTarget RenderTarget::CreateCompatibleRenderTarget(const D2D1_SIZE_F* desiredSize, const D2D1_SIZE_U* desiredPixelSize, const D2D1_PIXEL_FORMAT& desiredFormat)
            {
                ID2D1BitmapRenderTarget *pBitmapRenderTarget = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateCompatibleRenderTarget(desiredSize, desiredPixelSize, &desiredFormat,D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE,&pBitmapRenderTarget);
                CheckHRESULT(hr);

                BitmapRenderTarget result(pBitmapRenderTarget);
                return result;
            }

            HWIN_EXPORT BitmapRenderTarget RenderTarget::CreateCompatibleRenderTarget(const D2D1_SIZE_F* desiredSize, const D2D1_SIZE_U& desiredPixelSize, const D2D1_PIXEL_FORMAT* desiredFormat)
            {
                ID2D1BitmapRenderTarget *pBitmapRenderTarget = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateCompatibleRenderTarget(desiredSize, &desiredPixelSize, desiredFormat,D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE,&pBitmapRenderTarget);
                CheckHRESULT(hr);

                BitmapRenderTarget result(pBitmapRenderTarget);
                return result;
            }

            HWIN_EXPORT BitmapRenderTarget RenderTarget::CreateCompatibleRenderTarget(const D2D1_SIZE_F* desiredSize, const D2D1_SIZE_U& desiredPixelSize, const D2D1_PIXEL_FORMAT& desiredFormat)
            {
                ID2D1BitmapRenderTarget *pBitmapRenderTarget = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateCompatibleRenderTarget(desiredSize, &desiredPixelSize, &desiredFormat,D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE,&pBitmapRenderTarget);
                CheckHRESULT(hr);

                BitmapRenderTarget result(pBitmapRenderTarget);
                return result;
            }

            HWIN_EXPORT BitmapRenderTarget RenderTarget::CreateCompatibleRenderTarget(const D2D1_SIZE_F& desiredSize, const D2D1_SIZE_U* desiredPixelSize, const D2D1_PIXEL_FORMAT* desiredFormat)
            {
                ID2D1BitmapRenderTarget *pBitmapRenderTarget = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateCompatibleRenderTarget(&desiredSize, desiredPixelSize, desiredFormat,D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE,&pBitmapRenderTarget);
                CheckHRESULT(hr);

                BitmapRenderTarget result(pBitmapRenderTarget);
                return result;
            }

            HWIN_EXPORT BitmapRenderTarget RenderTarget::CreateCompatibleRenderTarget(const D2D1_SIZE_F& desiredSize, const D2D1_SIZE_U* desiredPixelSize, const D2D1_PIXEL_FORMAT& desiredFormat)
            {
                ID2D1BitmapRenderTarget *pBitmapRenderTarget = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateCompatibleRenderTarget(&desiredSize, desiredPixelSize, &desiredFormat,D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE,&pBitmapRenderTarget);
                CheckHRESULT(hr);

                BitmapRenderTarget result(pBitmapRenderTarget);
                return result;
            }

            HWIN_EXPORT BitmapRenderTarget RenderTarget::CreateCompatibleRenderTarget(const D2D1_SIZE_F& desiredSize, const D2D1_SIZE_U& desiredPixelSize, const D2D1_PIXEL_FORMAT& desiredFormat)
            {
                ID2D1BitmapRenderTarget *pBitmapRenderTarget = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateCompatibleRenderTarget(&desiredSize, &desiredPixelSize, &desiredFormat,D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE,&pBitmapRenderTarget);
                CheckHRESULT(hr);

                BitmapRenderTarget result(pBitmapRenderTarget);
                return result;
            }



            HWIN_EXPORT BitmapRenderTarget RenderTarget::CreateCompatibleRenderTarget(const D2D1_SIZE_F* desiredSize, const D2D1_SIZE_U* desiredPixelSize)
            {
                ID2D1BitmapRenderTarget *pBitmapRenderTarget = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateCompatibleRenderTarget(desiredSize, desiredPixelSize, nullptr,D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE,&pBitmapRenderTarget);
                CheckHRESULT(hr);

                BitmapRenderTarget result(pBitmapRenderTarget);
                return result;
            }

            HWIN_EXPORT BitmapRenderTarget RenderTarget::CreateCompatibleRenderTarget(const D2D1_SIZE_F* desiredSize, const D2D1_PIXEL_FORMAT* desiredFormat)
            {
                ID2D1BitmapRenderTarget *pBitmapRenderTarget = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateCompatibleRenderTarget(desiredSize, nullptr, desiredFormat,D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE,&pBitmapRenderTarget);
                CheckHRESULT(hr);

                BitmapRenderTarget result(pBitmapRenderTarget);
                return result;
            }

            HWIN_EXPORT BitmapRenderTarget RenderTarget::CreateCompatibleRenderTarget(const D2D1_SIZE_F* desiredSize)
            {
                ID2D1BitmapRenderTarget *pBitmapRenderTarget = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateCompatibleRenderTarget(desiredSize, nullptr, nullptr,D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE,&pBitmapRenderTarget);
                CheckHRESULT(hr);

                BitmapRenderTarget result(pBitmapRenderTarget);
                return result;
            }

                
            HWIN_EXPORT BitmapRenderTarget RenderTarget::CreateCompatibleRenderTarget(const D2D1_SIZE_F& desiredSize, const D2D1_SIZE_U* desiredPixelSize)
            {
                ID2D1BitmapRenderTarget *pBitmapRenderTarget = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateCompatibleRenderTarget(&desiredSize, desiredPixelSize, nullptr,D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE,&pBitmapRenderTarget);
                CheckHRESULT(hr);

                BitmapRenderTarget result(pBitmapRenderTarget);
                return result;
            }

            HWIN_EXPORT BitmapRenderTarget RenderTarget::CreateCompatibleRenderTarget(const D2D1_SIZE_F& desiredSize, const D2D1_SIZE_U& desiredPixelSize)
            {
                ID2D1BitmapRenderTarget *pBitmapRenderTarget = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateCompatibleRenderTarget(&desiredSize, &desiredPixelSize, nullptr,D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE,&pBitmapRenderTarget);
                CheckHRESULT(hr);

                BitmapRenderTarget result(pBitmapRenderTarget);
                return result;
            }

            HWIN_EXPORT BitmapRenderTarget RenderTarget::CreateCompatibleRenderTarget(const D2D1_SIZE_F& desiredSize, const D2D1_PIXEL_FORMAT* desiredFormat)
            {
                ID2D1BitmapRenderTarget *pBitmapRenderTarget = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateCompatibleRenderTarget(&desiredSize, nullptr, desiredFormat,D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE,&pBitmapRenderTarget);
                CheckHRESULT(hr);

                BitmapRenderTarget result(pBitmapRenderTarget);
                return result;
            }

            HWIN_EXPORT BitmapRenderTarget RenderTarget::CreateCompatibleRenderTarget(const D2D1_SIZE_F& desiredSize, const D2D1_PIXEL_FORMAT& desiredFormat)
            {
                ID2D1BitmapRenderTarget *pBitmapRenderTarget = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateCompatibleRenderTarget(&desiredSize, nullptr, &desiredFormat,D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE,&pBitmapRenderTarget);
                CheckHRESULT(hr);

                BitmapRenderTarget result(pBitmapRenderTarget);
                return result;
            }

            HWIN_EXPORT BitmapRenderTarget RenderTarget::CreateCompatibleRenderTarget(const D2D1_SIZE_F& desiredSize)
            {
                ID2D1BitmapRenderTarget *pBitmapRenderTarget = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateCompatibleRenderTarget(&desiredSize, nullptr, nullptr,D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE,&pBitmapRenderTarget);
                CheckHRESULT(hr);

                BitmapRenderTarget result(pBitmapRenderTarget);
                return result;
            }


            HWIN_EXPORT BitmapRenderTarget RenderTarget::CreateCompatibleRenderTarget( )
            {
                ID2D1BitmapRenderTarget *pBitmapRenderTarget = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateCompatibleRenderTarget(nullptr, nullptr, nullptr,D2D1_COMPATIBLE_RENDER_TARGET_OPTIONS_NONE,&pBitmapRenderTarget);
                CheckHRESULT(hr);

                BitmapRenderTarget result(pBitmapRenderTarget);
                return result;
            }


            HWIN_EXPORT Layer RenderTarget::CreateLayer(const D2D1_SIZE_F *size)
            {
                ID2D1Layer *pLayer = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateLayer(size,&pLayer);
                CheckHRESULT(hr);

                Layer result(pLayer);
                return result;
            }


            HWIN_EXPORT Layer RenderTarget::CreateLayer(const D2D1_SIZE_F& size)
            {
                ID2D1Layer *pLayer = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateLayer(&size,&pLayer);
                CheckHRESULT(hr);

                Layer result(pLayer);
                return result;
            }

            HWIN_EXPORT Layer RenderTarget::CreateLayer( )
            {
                ID2D1Layer *pLayer = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateLayer(nullptr,&pLayer);
                CheckHRESULT(hr);

                Layer result(pLayer);
                return result;
            }

            HWIN_EXPORT Mesh RenderTarget::CreateMesh( )
            {
                ID2D1Mesh *pMesh = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->CreateMesh(&pMesh);
                CheckHRESULT(hr);

                Mesh result(pMesh);
                return result;
            }

            HWIN_EXPORT RenderTarget& RenderTarget::DrawLine( D2D1_POINT_2F point0, D2D1_POINT_2F point1, ID2D1Brush *brush, FLOAT strokeWidth, ID2D1StrokeStyle *strokeStyle )
            {
                CheckPointerNotNull(brush);
                InterfaceType* pInterface = GetInterface();

                pInterface->DrawLine( point0, point1, brush, strokeWidth, strokeStyle );
                return *this;
            }


            HWIN_EXPORT RenderTarget& RenderTarget::DrawRectangle(const D2D1_RECT_F *rect, ID2D1Brush *brush, FLOAT strokeWidth , ID2D1StrokeStyle *strokeStyle )
            {
                CheckPointerNotNull(rect);
                CheckPointerNotNull(brush);

                InterfaceType* pInterface = GetInterface();
                pInterface->DrawRectangle(rect, brush, strokeWidth, strokeStyle );
                return *this;
            }

            HWIN_EXPORT RenderTarget& RenderTarget::DrawRectangle(const D2D1_RECT_F& rect, ID2D1Brush *brush, FLOAT strokeWidth, ID2D1StrokeStyle *strokeStyle )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->DrawRectangle(&rect, brush, strokeWidth, strokeStyle );
                return *this;
            }


            HWIN_EXPORT RenderTarget& RenderTarget::FillRectangle(const D2D1_RECT_F *rect, ID2D1Brush *brush )
            {
                CheckPointerNotNull(rect);
                CheckPointerNotNull(brush);

                InterfaceType* pInterface = GetInterface();
                pInterface->FillRectangle( rect, brush );
                return *this;
            }

            HWIN_EXPORT RenderTarget& RenderTarget::FillRectangle(const D2D1_RECT_F& rect, ID2D1Brush *brush )
            {
                CheckPointerNotNull(brush);

                InterfaceType* pInterface = GetInterface();
                pInterface->FillRectangle( &rect, brush );
                return *this;
            }

            HWIN_EXPORT RenderTarget& RenderTarget::DrawRoundedRectangle(const D2D1_ROUNDED_RECT *roundedRect, ID2D1Brush *brush, FLOAT strokeWidth, ID2D1StrokeStyle *strokeStyle )
            {
                CheckPointerNotNull(roundedRect);
                CheckPointerNotNull(brush);

                InterfaceType* pInterface = GetInterface();
                pInterface->DrawRoundedRectangle(roundedRect, brush, strokeWidth, strokeStyle);
                return *this;
            }

            HWIN_EXPORT RenderTarget& RenderTarget::DrawRoundedRectangle(const D2D1_ROUNDED_RECT& roundedRect, ID2D1Brush *brush, FLOAT strokeWidth, ID2D1StrokeStyle *strokeStyle )
            {
                CheckPointerNotNull(brush);

                InterfaceType* pInterface = GetInterface();
                pInterface->DrawRoundedRectangle(&roundedRect, brush, strokeWidth, strokeStyle);
                return *this;
            }

            HWIN_EXPORT RenderTarget& RenderTarget::FillRoundedRectangle(const D2D1_ROUNDED_RECT *roundedRect, ID2D1Brush *brush )
            {
                CheckPointerNotNull(roundedRect);
                CheckPointerNotNull(brush);

                InterfaceType* pInterface = GetInterface();
                pInterface->FillRoundedRectangle( roundedRect, brush );
                return *this;
            }

            HWIN_EXPORT RenderTarget& RenderTarget::FillRoundedRectangle(const D2D1_ROUNDED_RECT& roundedRect, ID2D1Brush *brush )
            {
                CheckPointerNotNull(brush);

                InterfaceType* pInterface = GetInterface();
                pInterface->FillRoundedRectangle( roundedRect, brush );
                return *this;
            }


            HWIN_EXPORT RenderTarget& RenderTarget::DrawEllipse(const D2D1_ELLIPSE* ellipse, ID2D1Brush *brush, FLOAT strokeWidth, ID2D1StrokeStyle *strokeStyle )
            {
                CheckPointerNotNull(ellipse);
                CheckPointerNotNull(brush);

                InterfaceType* pInterface = GetInterface();
                pInterface->DrawEllipse(ellipse, brush, strokeWidth, strokeStyle );
                return *this;
            }
            HWIN_EXPORT RenderTarget& RenderTarget::DrawEllipse(const D2D1_ELLIPSE& ellipse, ID2D1Brush *brush, FLOAT strokeWidth, ID2D1StrokeStyle *strokeStyle )
            {
                CheckPointerNotNull(brush);

                InterfaceType* pInterface = GetInterface();
                pInterface->DrawEllipse(&ellipse, brush, strokeWidth, strokeStyle );
                return *this;
            }
    
            HWIN_EXPORT RenderTarget& RenderTarget::FillEllipse(const D2D1_ELLIPSE* ellipse, ID2D1Brush *brush )
            {
                CheckPointerNotNull(ellipse);
                CheckPointerNotNull(brush);

                InterfaceType* pInterface = GetInterface();
                pInterface->FillEllipse(ellipse, brush );
                return *this;
            }
            HWIN_EXPORT RenderTarget& RenderTarget::FillEllipse(const D2D1_ELLIPSE& ellipse, ID2D1Brush *brush )
            {
                CheckPointerNotNull(brush);

                InterfaceType* pInterface = GetInterface();
                pInterface->FillEllipse(&ellipse, brush );
                return *this;
            }
    
            HWIN_EXPORT RenderTarget& RenderTarget::DrawGeometry( ID2D1Geometry *geometry, ID2D1Brush *brush, FLOAT strokeWidth, ID2D1StrokeStyle *strokeStyle )
            {
                CheckPointerNotNull(geometry);
                CheckPointerNotNull(brush);

                InterfaceType* pInterface = GetInterface();
                pInterface->DrawGeometry( geometry, brush, strokeWidth, strokeStyle );
                return *this;
            }


            HWIN_EXPORT RenderTarget& RenderTarget::FillGeometry( ID2D1Geometry *geometry, ID2D1Brush *brush,ID2D1Brush *opacityBrush )
            {
                CheckPointerNotNull(geometry);
                CheckPointerNotNull(brush);

                InterfaceType* pInterface = GetInterface();
                pInterface->FillGeometry( geometry, brush, opacityBrush );
                return *this;
            }


            HWIN_EXPORT RenderTarget& RenderTarget::FillMesh(ID2D1Mesh *mesh, ID2D1Brush *brush)
            {
                CheckPointerNotNull(mesh);
                CheckPointerNotNull(brush);

                InterfaceType* pInterface = GetInterface();
                pInterface->FillMesh( mesh, brush );
                return *this;
            }

            HWIN_EXPORT RenderTarget& RenderTarget::FillOpacityMask(ID2D1Bitmap *opacityMask, ID2D1Brush *brush, D2D1_OPACITY_MASK_CONTENT content, const D2D1_RECT_F *destinationRectangle, const D2D1_RECT_F *sourceRectangle)
            {
                CheckPointerNotNull(opacityMask);
                CheckPointerNotNull(brush);

                InterfaceType* pInterface = GetInterface();
                pInterface->FillOpacityMask( opacityMask, brush, content, destinationRectangle, sourceRectangle );
                return *this;
            }

            HWIN_EXPORT RenderTarget& RenderTarget::DrawBitmap(ID2D1Bitmap *bitmap, const D2D1_RECT_F *destinationRectangle, FLOAT opacity, D2D1_BITMAP_INTERPOLATION_MODE interpolationMode, const D2D1_RECT_F *sourceRectangle )
            {
                CheckPointerNotNull(bitmap);

                InterfaceType* pInterface = GetInterface();
                pInterface->DrawBitmap(bitmap, destinationRectangle, opacity, interpolationMode, sourceRectangle );
                return *this;
            }

            HWIN_EXPORT RenderTarget& RenderTarget::DrawText( const WCHAR *string, UINT32 stringLength, IDWriteTextFormat *textFormat, const D2D1_RECT_F *layoutRect, ID2D1Brush *defaultForegroundBrush, D2D1_DRAW_TEXT_OPTIONS options, DWRITE_MEASURING_MODE measuringMode )
            {
                CheckPointerNotNull(string);

                InterfaceType* pInterface = GetInterface();
                pInterface->DrawText( string, stringLength, textFormat, layoutRect, defaultForegroundBrush, options, measuringMode );
                return *this;
            }

            HWIN_EXPORT RenderTarget& RenderTarget::DrawText( const String& theText,
                                                            IDWriteTextFormat *textFormat,
                                                            const D2D1_RECT_F *layoutRect,
                                                            ID2D1Brush *defaultForegroundBrush,
                                                            D2D1_DRAW_TEXT_OPTIONS options,
                                                            DWRITE_MEASURING_MODE measuringMode )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->DrawText( theText.c_str(), UINT32(theText.length()), textFormat, layoutRect, defaultForegroundBrush, options, measuringMode );
                return *this;
            }


            HWIN_EXPORT RenderTarget& RenderTarget::DrawTextLayout(D2D1_POINT_2F origin,IDWriteTextLayout *textLayout,ID2D1Brush *defaultForegroundBrush,D2D1_DRAW_TEXT_OPTIONS options )
            {
                CheckPointerNotNull(textLayout);

                InterfaceType* pInterface = GetInterface();
                pInterface->DrawTextLayout(origin,textLayout,defaultForegroundBrush,options );
                return *this;
            }


            HWIN_EXPORT RenderTarget& RenderTarget::DrawGlyphRun(D2D1_POINT_2F baselineOrigin,const DWRITE_GLYPH_RUN *glyphRun, ID2D1Brush *foregroundBrush, DWRITE_MEASURING_MODE measuringMode)
            {
                CheckPointerNotNull(glyphRun);

                InterfaceType* pInterface = GetInterface();
                pInterface->DrawGlyphRun(baselineOrigin,glyphRun, foregroundBrush, measuringMode);
                return *this;
            }

            HWIN_EXPORT RenderTarget& RenderTarget::SetTransform(const D2D1_MATRIX_3X2_F *transform )
            {
                CheckPointerNotNull(transform);

                InterfaceType* pInterface = GetInterface();
                pInterface->SetTransform( transform );
                return *this;
            }


            HWIN_EXPORT const RenderTarget& RenderTarget::GetTransform(D2D1_MATRIX_3X2_F *transform ) const
            {
                CheckPointerNotNull(transform);

                InterfaceType* pInterface = GetInterface();
                pInterface->GetTransform( transform );
                return *this;
            }

            HWIN_EXPORT RenderTarget& RenderTarget::SetAntialiasMode( D2D1_ANTIALIAS_MODE antialiasMode )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->SetAntialiasMode( antialiasMode );
                return *this;
            }

            HWIN_EXPORT D2D1_ANTIALIAS_MODE RenderTarget::GetAntialiasMode( ) const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetAntialiasMode( );
            }

            HWIN_EXPORT RenderTarget& RenderTarget::SetTextAntialiasMode( D2D1_TEXT_ANTIALIAS_MODE textAntialiasMode )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->SetTextAntialiasMode( textAntialiasMode );
                return *this;
            }

            HWIN_EXPORT D2D1_TEXT_ANTIALIAS_MODE RenderTarget::GetTextAntialiasMode( ) const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetTextAntialiasMode( );
            }

            HWIN_EXPORT RenderTarget& RenderTarget::SetTextRenderingParams( IDWriteRenderingParams *textRenderingParams )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->SetTextRenderingParams( textRenderingParams );
                return *this;
            }

            HWIN_EXPORT const RenderTarget& RenderTarget::GetTextRenderingParams( IDWriteRenderingParams **textRenderingParams ) const
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->GetTextRenderingParams( textRenderingParams );
                return *this;
            }

            HWIN_EXPORT RenderTarget& RenderTarget::SetTags(D2D1_TAG tag1, D2D1_TAG tag2)
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->SetTags(tag1, tag2);
                return *this;
            }

            HWIN_EXPORT const RenderTarget& RenderTarget::GetTags( D2D1_TAG *tag1, D2D1_TAG *tag2 ) const
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->GetTags( tag1, tag2 );
                return *this;
            }

            HWIN_EXPORT RenderTarget& RenderTarget::PushLayer(const D2D1_LAYER_PARAMETERS *layerParameters, ID2D1Layer *layer )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->PushLayer(layerParameters, layer );
                return *this;
            }

            HWIN_EXPORT RenderTarget& RenderTarget::PopLayer( )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->PopLayer( );
                return *this;
            }


            HWIN_EXPORT RenderTarget& RenderTarget::Flush(D2D1_TAG *tag1, D2D1_TAG *tag2)
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->Flush(tag1, tag2);
                return *this;
            }

            HWIN_EXPORT RenderTarget& RenderTarget::SaveDrawingState(ID2D1DrawingStateBlock *drawingStateBlock)
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->SaveDrawingState(drawingStateBlock);
                return *this;
            }

            HWIN_EXPORT RenderTarget& RenderTarget::RestoreDrawingState( ID2D1DrawingStateBlock *drawingStateBlock)
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->RestoreDrawingState( drawingStateBlock);
                return *this;
            }

            HWIN_EXPORT RenderTarget& RenderTarget::PushAxisAlignedClip(const D2D1_RECT_F *clipRect, D2D1_ANTIALIAS_MODE antialiasMode )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->PushAxisAlignedClip(clipRect, antialiasMode );
                return *this;
            }

            HWIN_EXPORT RenderTarget& RenderTarget::PopAxisAlignedClip( )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->PopAxisAlignedClip( );
                return *this;
            }


            HWIN_EXPORT RenderTarget& RenderTarget::Clear(const D2D1_COLOR_F *clearColor)
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->Clear(clearColor);
                return *this;
            }

            HWIN_EXPORT RenderTarget& RenderTarget::BeginDraw( )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->BeginDraw( );
                return *this;
            }

            HWIN_EXPORT RenderTarget& RenderTarget::EndDraw( D2D1_TAG *tag1, D2D1_TAG *tag2 )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->EndDraw( tag1, tag2 );
                return *this;
            }

            HWIN_EXPORT D2D1_PIXEL_FORMAT RenderTarget::GetPixelFormat( ) const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetPixelFormat( );
            }

            HWIN_EXPORT RenderTarget& RenderTarget::SetDpi( FLOAT dpiX, FLOAT dpiY )
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->SetDpi( dpiX, dpiY );
                return *this;
            }

            HWIN_EXPORT const RenderTarget& RenderTarget::GetDpi( FLOAT *dpiX, FLOAT *dpiY ) const
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->GetDpi( dpiX, dpiY );
                return *this;
            }

            HWIN_EXPORT D2D1_SIZE_F RenderTarget::GetSize( ) const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetSize( );
            }

            HWIN_EXPORT D2D1_SIZE_U RenderTarget::GetPixelSize( ) const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetPixelSize( );
            }

            HWIN_EXPORT UINT32 RenderTarget::GetMaximumBitmapSize( ) const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetMaximumBitmapSize( );
            }

            HWIN_EXPORT bool RenderTarget::IsSupported(const D2D1_RENDER_TARGET_PROPERTIES *renderTargetProperties ) const
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->IsSupported( renderTargetProperties ) != FALSE;
            }

            // ================================================================
            // BitmapRenderTarget
            // ================================================================
            HWIN_EXPORT const BitmapRenderTarget& BitmapRenderTarget::GetBitmap(ID2D1Bitmap **bitmap ) const
            {
                CheckPointerNotNull(bitmap);
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetBitmap(bitmap);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT Bitmap BitmapRenderTarget::GetBitmap( ) const
            {
                ID2D1Bitmap* pBitmap = nullptr;
                InterfaceType* pInterface = GetInterface();

                HRESULT hr = pInterface->GetBitmap(&pBitmap);
                CheckHRESULT(hr);

                Bitmap result(pBitmap);
                return result;
            }


            // ================================================================
            // ControlRenderTarget
            // ================================================================

            HWIN_EXPORT D2D1_WINDOW_STATE ControlRenderTarget::CheckWindowState( )
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->CheckWindowState( );
            }

            HWIN_EXPORT ControlRenderTarget& ControlRenderTarget::Resize(const D2D1_SIZE_U *pixelSize )
            {
                CheckPointerNotNull(pixelSize);

                InterfaceType* pInterface = GetInterface();

                pInterface->Resize( pixelSize );

                return *this;
            }

            HWIN_EXPORT HWND ControlRenderTarget::GetHwnd( ) const
            {
                InterfaceType* pInterface = GetInterface();

                return pInterface->GetHwnd( );
            }


            // ================================================================
            // GdiInteropRenderTarget
            // ================================================================
            HWIN_EXPORT GdiInteropRenderTarget& GdiInteropRenderTarget::GetDC(D2D1_DC_INITIALIZE_MODE mode, HDC *hdc )
            {
                CheckPointerNotNull(hdc);

                InterfaceType* pInterface = GetInterface();

                pInterface->GetDC(mode, hdc );

                return *this;
            }
    
            HWIN_EXPORT GdiInteropRenderTarget& GdiInteropRenderTarget::ReleaseDC(const RECT *update )
            {

                InterfaceType* pInterface = GetInterface();

                pInterface->ReleaseDC( update );

                return *this;
            }

            // ================================================================
            // DeviceContextRenderTarget
            // ================================================================
            HWIN_EXPORT DeviceContextRenderTarget& DeviceContextRenderTarget::BindDC(const HDC hDC,const RECT *pSubRect )
            {
                CheckPointerNotNull(pSubRect);

                InterfaceType* pInterface = GetInterface();

                pInterface->BindDC(hDC, pSubRect );

                return *this;
            }

            HWIN_EXPORT DeviceContextRenderTarget& DeviceContextRenderTarget::BindDC(const HDC hDC,const RECT& pSubRect )
            {
                InterfaceType* pInterface = GetInterface();

                pInterface->BindDC(hDC, &pSubRect );

                return *this;
            }

            // ================================================================
            // Factory
            // ================================================================
            HWIN_EXPORT Factory::Factory(D2D1_FACTORY_TYPE factoryType)
            {
                InterfaceType* pInterface = nullptr;
                HRESULT hr = D2D1CreateFactory(factoryType,&pInterface);
                CheckHRESULT(hr);
                unknown = pInterface;
            }

            HWIN_EXPORT Factory& Factory::ReloadSystemMetrics()
            {
                InterfaceType* pInterface = GetInterface();
                
                HRESULT hr = pInterface->ReloadSystemMetrics();
                CheckHRESULT(hr);

                return *this;
            }

            HWIN_EXPORT const Factory& Factory::GetDesktopDpi(FLOAT *dpiX, FLOAT *dpiY) const
            {
                CheckPointerNotNull(dpiX);
                CheckPointerNotNull(dpiY);
                InterfaceType* pInterface = GetInterface();

                pInterface->GetDesktopDpi(dpiX, dpiY);

                return *this;
            }
            HWIN_EXPORT const Factory& Factory::GetDesktopDpi(FLOAT& dpiX, FLOAT& dpiY) const
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->GetDesktopDpi(&dpiX, &dpiY);
                return *this;
            }
            HWIN_EXPORT D2D1_SIZE_F Factory::GetDesktopDpi() const
            {
                D2D1_SIZE_F result = {0.0f,};
                InterfaceType* pInterface = GetInterface();
                pInterface->GetDesktopDpi(&result.width, &result.height);
                return result;
            }


            HWIN_EXPORT RectangleGeometry Factory::CreateRectangleGeometry(const D2D1_RECT_F* rectangle) const
            {
                CheckPointerNotNull(rectangle);
                InterfaceType* pInterface = GetInterface();
                ID2D1RectangleGeometry* pRectangleGeometry = nullptr;
                HRESULT hr = pInterface->CreateRectangleGeometry(rectangle,&pRectangleGeometry);
                CheckHRESULT(hr);
                RectangleGeometry result(pRectangleGeometry);
                return result;
            }
            HWIN_EXPORT RectangleGeometry Factory::CreateRectangleGeometry(const D2D1_RECT_F& rectangle) const
            {
                return CreateRectangleGeometry(&rectangle);
            }
            HWIN_EXPORT RectangleGeometry Factory::CreateRectangleGeometry(const D2D1_POINT_2F* position, const D2D1_SIZE_F* size) const
            {
                CheckPointerNotNull(position);
                CheckPointerNotNull(size);
                D2D1_RECT_F rectangle = { position->x,position->y,size->width + position->x, size->height + position->y };
                return CreateRectangleGeometry(&rectangle);
            }
            HWIN_EXPORT RectangleGeometry Factory::CreateRectangleGeometry(const D2D1_POINT_2F& position, const D2D1_SIZE_F& size) const
            {
                D2D1_RECT_F rectangle = { position.x,position.y,size.width + position.x, size.height + position.y };
                return CreateRectangleGeometry(&rectangle);
            }

            HWIN_EXPORT RectangleGeometry Factory::CreateRectangleGeometry(FLOAT left,FLOAT top,FLOAT right, FLOAT bottom) const
            {
                D2D1_RECT_F rectangle = { left,top,right, bottom };
                return CreateRectangleGeometry(&rectangle);
            }


            HWIN_EXPORT RoundedRectangleGeometry Factory::CreateRoundedRectangleGeometry(const D2D1_ROUNDED_RECT* roundedRectangle) const
            {
                CheckPointerNotNull(roundedRectangle);
                InterfaceType* pInterface = GetInterface();
                ID2D1RoundedRectangleGeometry* pRoundedRectangleGeometry = nullptr;
                HRESULT hr = pInterface->CreateRoundedRectangleGeometry(roundedRectangle,&pRoundedRectangleGeometry);
                CheckHRESULT(hr);
                RoundedRectangleGeometry result(pRoundedRectangleGeometry);
                return result;
            }
            HWIN_EXPORT RoundedRectangleGeometry Factory::CreateRoundedRectangleGeometry(const D2D1_ROUNDED_RECT& roundedRectangle) const
            {
                InterfaceType* pInterface = GetInterface();
                ID2D1RoundedRectangleGeometry* pRoundedRectangleGeometry = nullptr;
                HRESULT hr = pInterface->CreateRoundedRectangleGeometry(&roundedRectangle,&pRoundedRectangleGeometry);
                CheckHRESULT(hr);
                RoundedRectangleGeometry result(pRoundedRectangleGeometry);
                return result;
            }

            HWIN_EXPORT RoundedRectangleGeometry Factory::CreateRoundedRectangleGeometry(const D2D1_RECT_F* rectangle, FLOAT radiusX, FLOAT readiusY ) const
            {
                CheckPointerNotNull(rectangle);
                D2D1_ROUNDED_RECT roundedRectangle = {{rectangle->left,rectangle->top,rectangle->right,rectangle->bottom},radiusX, readiusY};
                InterfaceType* pInterface = GetInterface();
                ID2D1RoundedRectangleGeometry* pRoundedRectangleGeometry = nullptr;
                HRESULT hr = pInterface->CreateRoundedRectangleGeometry(&roundedRectangle,&pRoundedRectangleGeometry);
                CheckHRESULT(hr);
                RoundedRectangleGeometry result(pRoundedRectangleGeometry);
                return result;
            }

            HWIN_EXPORT RoundedRectangleGeometry Factory::CreateRoundedRectangleGeometry(const D2D1_RECT_F& rectangle, FLOAT radiusX, FLOAT readiusY ) const
            {
                D2D1_ROUNDED_RECT roundedRectangle = {{rectangle.left,rectangle.top,rectangle.right,rectangle.bottom},radiusX, readiusY};
                InterfaceType* pInterface = GetInterface();
                ID2D1RoundedRectangleGeometry* pRoundedRectangleGeometry = nullptr;
                HRESULT hr = pInterface->CreateRoundedRectangleGeometry(&roundedRectangle,&pRoundedRectangleGeometry);
                CheckHRESULT(hr);
                RoundedRectangleGeometry result(pRoundedRectangleGeometry);
                return result;
            }

            HWIN_EXPORT RoundedRectangleGeometry Factory::CreateRoundedRectangleGeometry(const D2D1_POINT_2F* position, const D2D1_SIZE_F* size, FLOAT radiusX, FLOAT readiusY) const
            {
                CheckPointerNotNull(position);
                CheckPointerNotNull(size);
                D2D1_ROUNDED_RECT roundedRectangle = {{position->x,position->y,position->x + size->width,position->y+size->height},radiusX, readiusY};
                InterfaceType* pInterface = GetInterface();
                ID2D1RoundedRectangleGeometry* pRoundedRectangleGeometry = nullptr;
                HRESULT hr = pInterface->CreateRoundedRectangleGeometry(&roundedRectangle,&pRoundedRectangleGeometry);
                CheckHRESULT(hr);
                RoundedRectangleGeometry result(pRoundedRectangleGeometry);
                return result;
            }

            HWIN_EXPORT RoundedRectangleGeometry Factory::CreateRoundedRectangleGeometry(const D2D1_POINT_2F& position, const D2D1_SIZE_F& size, FLOAT radiusX, FLOAT readiusY) const
            {
                D2D1_ROUNDED_RECT roundedRectangle = {{position.x,position.y,position.x + size.width,position.y+size.height},radiusX, readiusY};
                InterfaceType* pInterface = GetInterface();
                ID2D1RoundedRectangleGeometry* pRoundedRectangleGeometry = nullptr;
                HRESULT hr = pInterface->CreateRoundedRectangleGeometry(&roundedRectangle,&pRoundedRectangleGeometry);
                CheckHRESULT(hr);
                RoundedRectangleGeometry result(pRoundedRectangleGeometry);
                return result;
            }

            HWIN_EXPORT RoundedRectangleGeometry Factory::CreateRoundedRectangleGeometry(FLOAT left,FLOAT top,FLOAT right, FLOAT bottom, FLOAT radiusX, FLOAT readiusY) const
            {
                D2D1_ROUNDED_RECT roundedRectangle = {{left,top,right,bottom},radiusX, readiusY};
                InterfaceType* pInterface = GetInterface();
                ID2D1RoundedRectangleGeometry* pRoundedRectangleGeometry = nullptr;
                HRESULT hr = pInterface->CreateRoundedRectangleGeometry(&roundedRectangle,&pRoundedRectangleGeometry);
                CheckHRESULT(hr);
                RoundedRectangleGeometry result(pRoundedRectangleGeometry);
                return result;
            }


            HWIN_EXPORT EllipseGeometry Factory::CreateEllipseGeometry(const D2D1_ELLIPSE *ellipse)
            {
                CheckPointerNotNull(ellipse);
                InterfaceType* pInterface = GetInterface();
                ID2D1EllipseGeometry* pEllipseGeometry = nullptr;
                HRESULT hr = pInterface->CreateEllipseGeometry(ellipse,&pEllipseGeometry);
                CheckHRESULT(hr);
                EllipseGeometry result(pEllipseGeometry);
                return result;
            }


            HWIN_EXPORT GeometryGroup Factory::CreateGeometryGroup(D2D1_FILL_MODE fillMode,ID2D1Geometry **geometries, UINT32 geometriesCount )
            {
                CheckPointerNotNull(geometries);
                InterfaceType* pInterface = GetInterface();
                ID2D1GeometryGroup* pGeometryGroup = nullptr;
                HRESULT hr = pInterface->CreateGeometryGroup(fillMode,geometries, geometriesCount,&pGeometryGroup);
                CheckHRESULT(hr);
                GeometryGroup result(pGeometryGroup);
                return result;
            }


            HWIN_EXPORT TransformedGeometry Factory::CreateTransformedGeometry(ID2D1Geometry *sourceGeometry,const D2D1_MATRIX_3X2_F *transform )
            {
                CheckPointerNotNull(sourceGeometry);
                CheckPointerNotNull(transform);
                InterfaceType* pInterface = GetInterface();
                ID2D1TransformedGeometry* pTransformedGeometry = nullptr;
                HRESULT hr = pInterface->CreateTransformedGeometry(sourceGeometry,transform,&pTransformedGeometry);
                CheckHRESULT(hr);
                TransformedGeometry result(pTransformedGeometry);
                return result;
            }

            HWIN_EXPORT PathGeometry Factory::CreatePathGeometry( )
            {
                InterfaceType* pInterface = GetInterface();
                ID2D1PathGeometry* pPathGeometry = nullptr;
                HRESULT hr = pInterface->CreatePathGeometry(&pPathGeometry);
                CheckHRESULT(hr);
                PathGeometry result(pPathGeometry);
                return result;
            }


            HWIN_EXPORT StrokeStyle Factory::CreateStrokeStyle(const D2D1_STROKE_STYLE_PROPERTIES *strokeStyleProperties,const FLOAT *dashes, UINT32 dashesCount )
            {
                CheckPointerNotNull(strokeStyleProperties);
                
                InterfaceType* pInterface = GetInterface();
                ID2D1StrokeStyle* pStrokeStyle = nullptr;
                HRESULT hr = pInterface->CreateStrokeStyle(strokeStyleProperties,dashes, dashesCount,&pStrokeStyle);
                CheckHRESULT(hr);
                StrokeStyle result(pStrokeStyle);
                return result;
            }

            HWIN_EXPORT StrokeStyle Factory::CreateStrokeStyle(const D2D1_STROKE_STYLE_PROPERTIES *strokeStyleProperties)
            {
                CheckPointerNotNull(strokeStyleProperties);
                
                InterfaceType* pInterface = GetInterface();
                ID2D1StrokeStyle* pStrokeStyle = nullptr;
                HRESULT hr = pInterface->CreateStrokeStyle(strokeStyleProperties,nullptr, 0,&pStrokeStyle);
                CheckHRESULT(hr);
                StrokeStyle result(pStrokeStyle);
                return result;
            }


            HWIN_EXPORT DrawingStateBlock Factory::CreateDrawingStateBlock(const D2D1_DRAWING_STATE_DESCRIPTION *drawingStateDescription, IDWriteRenderingParams *textRenderingParams )
            {
                InterfaceType* pInterface = GetInterface();
                ID2D1DrawingStateBlock* pDrawingStateBlock = nullptr;
                HRESULT hr = pInterface->CreateDrawingStateBlock(drawingStateDescription, textRenderingParams,&pDrawingStateBlock);
                CheckHRESULT(hr);
                DrawingStateBlock result(pDrawingStateBlock);
                return result;
            }

            HWIN_EXPORT DrawingStateBlock Factory::CreateDrawingStateBlock(const D2D1_DRAWING_STATE_DESCRIPTION *drawingStateDescription  )
            {
                InterfaceType* pInterface = GetInterface();
                ID2D1DrawingStateBlock* pDrawingStateBlock = nullptr;
                HRESULT hr = pInterface->CreateDrawingStateBlock(drawingStateDescription, nullptr,&pDrawingStateBlock);
                CheckHRESULT(hr);
                DrawingStateBlock result(pDrawingStateBlock);
                return result;
            }

            HWIN_EXPORT DrawingStateBlock Factory::CreateDrawingStateBlock(const D2D1_DRAWING_STATE_DESCRIPTION& drawingStateDescription  )
            {
                InterfaceType* pInterface = GetInterface();
                ID2D1DrawingStateBlock* pDrawingStateBlock = nullptr;
                HRESULT hr = pInterface->CreateDrawingStateBlock(&drawingStateDescription, nullptr,&pDrawingStateBlock);
                CheckHRESULT(hr);
                DrawingStateBlock result(pDrawingStateBlock);
                return result;
            }

            HWIN_EXPORT DrawingStateBlock Factory::CreateDrawingStateBlock(IDWriteRenderingParams *textRenderingParams )
            {
                InterfaceType* pInterface = GetInterface();
                ID2D1DrawingStateBlock* pDrawingStateBlock = nullptr;
                HRESULT hr = pInterface->CreateDrawingStateBlock(nullptr, textRenderingParams,&pDrawingStateBlock);
                CheckHRESULT(hr);
                DrawingStateBlock result(pDrawingStateBlock);
                return result;
            }

            HWIN_EXPORT DrawingStateBlock Factory::CreateDrawingStateBlock( )
            {
                InterfaceType* pInterface = GetInterface();
                ID2D1DrawingStateBlock* pDrawingStateBlock = nullptr;
                HRESULT hr = pInterface->CreateDrawingStateBlock(nullptr, nullptr,&pDrawingStateBlock);
                CheckHRESULT(hr);
                DrawingStateBlock result(pDrawingStateBlock);
                return result;
            }


            HWIN_EXPORT RenderTarget Factory::CreateWicBitmapRenderTarget(IWICBitmap *target,const D2D1_RENDER_TARGET_PROPERTIES* renderTargetProperties)
            {
                CheckPointerNotNull(target);
                CheckPointerNotNull(renderTargetProperties);
                InterfaceType* pInterface = GetInterface();
                ID2D1RenderTarget* pRenderTarget = nullptr;
                HRESULT hr = pInterface->CreateWicBitmapRenderTarget(target, renderTargetProperties,&pRenderTarget);
                CheckHRESULT(hr);
                RenderTarget result(pRenderTarget);
                return result;
            }

            HWIN_EXPORT RenderTarget Factory::CreateWicBitmapRenderTarget(IWICBitmap *target,const D2D1_RENDER_TARGET_PROPERTIES& renderTargetProperties)
            {
                CheckPointerNotNull(target);
                InterfaceType* pInterface = GetInterface();
                ID2D1RenderTarget* pRenderTarget = nullptr;
                HRESULT hr = pInterface->CreateWicBitmapRenderTarget(target, &renderTargetProperties,&pRenderTarget);
                CheckHRESULT(hr);
                RenderTarget result(pRenderTarget);
                return result;
            }


            HWIN_EXPORT ControlRenderTarget Factory::CreateControlRenderTarget( std::shared_ptr<Control> control ) const
            {
                CheckPointerNotNull(control);
                InterfaceType* pInterface = GetInterface();
                HWND hwnd = control->GetSafeHandle();
                RECT rect;
                control->GetClientRect(rect);

                ID2D1HwndRenderTarget* pRenderTarget = NULL;
                HRESULT hr = pInterface->CreateHwndRenderTarget(
                    D2D1::RenderTargetProperties(),
                    D2D1::HwndRenderTargetProperties( hwnd, D2D1::SizeU( rect.right - rect.left, rect.bottom - rect.top) ), &pRenderTarget);
                CheckHRESULT(hr);

                ControlRenderTarget result(pRenderTarget);
                return result;

            }

            HWIN_EXPORT ControlRenderTarget Factory::CreateControlRenderTarget( HWND hwnd ) const
            {
                InterfaceType* pInterface = GetInterface();
                RECT rect;
                if(GetClientRect(hwnd,&rect) == FALSE)
                {
                    ThrowLastOSError();
                }

                ID2D1HwndRenderTarget* pRenderTarget = NULL;
                HRESULT hr = pInterface->CreateHwndRenderTarget(
                    D2D1::RenderTargetProperties(),
                    D2D1::HwndRenderTargetProperties( hwnd, D2D1::SizeU( rect.right - rect.left, rect.bottom - rect.top) ), &pRenderTarget);
                CheckHRESULT(hr);

                ControlRenderTarget result(pRenderTarget);
                return result;
            }


            HWIN_EXPORT RenderTarget Factory::CreateDxgiSurfaceRenderTarget(IDXGISurface *dxgiSurface,const D2D1_RENDER_TARGET_PROPERTIES* renderTargetProperties )
            {
                CheckPointerNotNull(dxgiSurface);
                CheckPointerNotNull(renderTargetProperties);
                InterfaceType* pInterface = GetInterface();
                ID2D1RenderTarget* pRenderTarget = nullptr;
                HRESULT hr = pInterface->CreateDxgiSurfaceRenderTarget(dxgiSurface, renderTargetProperties,&pRenderTarget);
                CheckHRESULT(hr);
                RenderTarget result(pRenderTarget);
                return result;
            }
            HWIN_EXPORT RenderTarget Factory::CreateDxgiSurfaceRenderTarget(IDXGISurface *dxgiSurface,const D2D1_RENDER_TARGET_PROPERTIES& renderTargetProperties )
            {
                CheckPointerNotNull(dxgiSurface);
                InterfaceType* pInterface = GetInterface();
                ID2D1RenderTarget* pRenderTarget = nullptr;
                HRESULT hr = pInterface->CreateDxgiSurfaceRenderTarget(dxgiSurface, &renderTargetProperties,&pRenderTarget);
                CheckHRESULT(hr);
                RenderTarget result(pRenderTarget);
                return result;
            }

            HWIN_EXPORT RenderTarget Factory::CreateDxgiSurfaceRenderTarget(IDXGISurface *dxgiSurface)
            {
                CheckPointerNotNull(dxgiSurface);
                InterfaceType* pInterface = GetInterface();

                FLOAT dpiX;
                FLOAT dpiY;
                pInterface->GetDesktopDpi(&dpiX, &dpiY);

                D2D1_RENDER_TARGET_PROPERTIES props = D2D1::RenderTargetProperties(D2D1_RENDER_TARGET_TYPE_DEFAULT, D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED), dpiX,dpiY);

                
                ID2D1RenderTarget* pRenderTarget = nullptr;
                HRESULT hr = pInterface->CreateDxgiSurfaceRenderTarget(dxgiSurface, &props,&pRenderTarget);
                CheckHRESULT(hr);
                RenderTarget result(pRenderTarget);
                return result;
            }


            HWIN_EXPORT DeviceContextRenderTarget Factory::CreateDCRenderTarget(const D2D1_RENDER_TARGET_PROPERTIES* renderTargetProperties)
            {
                CheckPointerNotNull(renderTargetProperties);
                InterfaceType* pInterface = GetInterface();
                ID2D1DCRenderTarget* pRenderTarget = nullptr;
                HRESULT hr = pInterface->CreateDCRenderTarget(renderTargetProperties,&pRenderTarget);
                CheckHRESULT(hr);
                DeviceContextRenderTarget result(pRenderTarget);
                return result;
            }

            HWIN_EXPORT DeviceContextRenderTarget Factory::CreateDCRenderTarget(const D2D1_RENDER_TARGET_PROPERTIES& renderTargetProperties)
            {
                InterfaceType* pInterface = GetInterface();
                ID2D1DCRenderTarget* pRenderTarget = nullptr;
                HRESULT hr = pInterface->CreateDCRenderTarget(&renderTargetProperties,&pRenderTarget);
                CheckHRESULT(hr);
                DeviceContextRenderTarget result(pRenderTarget);
                return result;
            }


            HWIN_EXPORT DeviceContextRenderTarget Factory::CreateDCRenderTarget( )
            {
                InterfaceType* pInterface = GetInterface();
                ID2D1DCRenderTarget* pRenderTarget = nullptr;

                D2D1_RENDER_TARGET_PROPERTIES renderTargetProperties = D2D1::RenderTargetProperties(
                            D2D1_RENDER_TARGET_TYPE_DEFAULT,
                            D2D1::PixelFormat(
                                DXGI_FORMAT_B8G8R8A8_UNORM,
                                D2D1_ALPHA_MODE_IGNORE),
                            0,
                            0,
                            D2D1_RENDER_TARGET_USAGE_NONE,
                            D2D1_FEATURE_LEVEL_DEFAULT);


                HRESULT hr = pInterface->CreateDCRenderTarget(&renderTargetProperties,&pRenderTarget);
                CheckHRESULT(hr);
                DeviceContextRenderTarget result(pRenderTarget);
                return result;
            }


            // ================================================================
            // WriteFontFileLoader
            // ================================================================
            HWIN_EXPORT WriteFontFileLoader& WriteFontFileLoader::CreateStreamFromKey(void const* fontFileReferenceKey,UINT32 fontFileReferenceKeySize,_Out_ IDWriteFontFileStream** fontFileStream)
            {

                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateStreamFromKey(fontFileReferenceKey,fontFileReferenceKeySize,fontFileStream);
                CheckHRESULT(hr);
                return *this;

            }
            HWIN_EXPORT WriteFontFileStream WriteFontFileLoader::CreateStreamFromKey(void const* fontFileReferenceKey,UINT32 fontFileReferenceKeySize)
            {
                IDWriteFontFileStream* fontFileStream = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateStreamFromKey(fontFileReferenceKey,fontFileReferenceKeySize,&fontFileStream);
                CheckHRESULT(hr);
                WriteFontFileStream result(fontFileStream);
                return result;
            }
            // ================================================================
            // WriteLocalFontFileLoader
            // ================================================================
            HWIN_EXPORT WriteLocalFontFileLoader& WriteLocalFontFileLoader::GetFilePathLengthFromKey(void const* fontFileReferenceKey,UINT32 fontFileReferenceKeySize,_Out_ UINT32* filePathLength)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFilePathLengthFromKey(fontFileReferenceKey,fontFileReferenceKeySize,filePathLength);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT UINT32 WriteLocalFontFileLoader::GetFilePathLengthFromKey(void const* fontFileReferenceKey,UINT32 fontFileReferenceKeySize)
            {
                UINT32 result = 0;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFilePathLengthFromKey(fontFileReferenceKey,fontFileReferenceKeySize,&result);
                CheckHRESULT(hr);
                return result;
            }

            HWIN_EXPORT WriteLocalFontFileLoader& WriteLocalFontFileLoader::GetFilePathFromKey(void const* fontFileReferenceKey,UINT32 fontFileReferenceKeySize, WCHAR* filePath,UINT32 filePathSize)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFilePathFromKey(fontFileReferenceKey,fontFileReferenceKeySize, filePath,filePathSize);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT std::shared_ptr<String> WriteLocalFontFileLoader::GetFilePathFromKey(void const* fontFileReferenceKey,UINT32 fontFileReferenceKeySize)
            {
                UINT32 filePathSize = GetFilePathLengthFromKey(fontFileReferenceKey,fontFileReferenceKeySize);

                std::shared_ptr<String> result = std::make_shared<String>(filePathSize,String::value_type(0));

                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFilePathFromKey(fontFileReferenceKey,fontFileReferenceKeySize,  const_cast<WCHAR*>(result->c_str()),filePathSize);
                CheckHRESULT(hr);
                return result;
            }

            HWIN_EXPORT WriteLocalFontFileLoader& WriteLocalFontFileLoader::GetLastWriteTimeFromKey(void const* fontFileReferenceKey,UINT32 fontFileReferenceKeySize,_Out_ FILETIME* lastWriteTime)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetLastWriteTimeFromKey(fontFileReferenceKey,fontFileReferenceKeySize,lastWriteTime);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT FILETIME WriteLocalFontFileLoader::GetLastWriteTimeFromKey(void const* fontFileReferenceKey,UINT32 fontFileReferenceKeySize)
            {
                FILETIME result;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetLastWriteTimeFromKey(fontFileReferenceKey,fontFileReferenceKeySize,&result);
                CheckHRESULT(hr);
                return result;
            }

            // ================================================================
            // WriteFontFileStream
            // ================================================================
            HWIN_EXPORT WriteFontFileStream& WriteFontFileStream::ReadFileFragment(void const** fragmentStart,UINT64 fileOffset,UINT64 fragmentSize,_Out_ void** fragmentContext)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->ReadFileFragment(fragmentStart,fileOffset,fragmentSize,fragmentContext);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteFontFileStream& WriteFontFileStream::ReleaseFileFragment(void* fragmentContext)
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->ReleaseFileFragment(fragmentContext);
                return *this;
            }

            HWIN_EXPORT WriteFontFileStream& WriteFontFileStream::GetFileSize(_Out_ UINT64* fileSize)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFileSize(fileSize);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT UINT64 WriteFontFileStream::GetFileSize( )
            {
                UINT64 result = 0;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFileSize(&result);
                CheckHRESULT(hr);
                return result;
            }

            HWIN_EXPORT WriteFontFileStream& WriteFontFileStream::GetLastWriteTime(_Out_ UINT64* lastWriteTime)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetLastWriteTime(lastWriteTime);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT UINT64 WriteFontFileStream::GetLastWriteTime()
            {
                UINT64 result = 0;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetLastWriteTime(&result);
                CheckHRESULT(hr);
                return result;
            }

            // ================================================================
            // WriteFontFile
            // ================================================================
            HWIN_EXPORT WriteFontFile& WriteFontFile::GetReferenceKey(void const** fontFileReferenceKey,_Out_ UINT32* fontFileReferenceKeySize)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetReferenceKey(fontFileReferenceKey,fontFileReferenceKeySize);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteFontFile& WriteFontFile::GetLoader(_Out_ IDWriteFontFileLoader** fontFileLoader)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetLoader(fontFileLoader);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteFontFileLoader WriteFontFile::GetLoader( )
            {
                IDWriteFontFileLoader* fontFileLoader = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetLoader(&fontFileLoader);
                CheckHRESULT(hr);
                WriteFontFileLoader result(fontFileLoader);
                return result;
            }
            HWIN_EXPORT WriteFontFile& WriteFontFile::Analyze(_Out_ BOOL* isSupportedFontType,_Out_ DWRITE_FONT_FILE_TYPE* fontFileType, _Out_opt_ DWRITE_FONT_FACE_TYPE* fontFaceType, _Out_ UINT32* numberOfFaces)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->Analyze(isSupportedFontType,fontFileType, fontFaceType, numberOfFaces);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteFontFile& WriteFontFile::Analyze(_Out_ BOOL& isSupportedFontType,_Out_ DWRITE_FONT_FILE_TYPE& fontFileType, _Out_opt_ DWRITE_FONT_FACE_TYPE& fontFaceType, _Out_ UINT32& numberOfFaces)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->Analyze(&isSupportedFontType,&fontFileType, &fontFaceType, &numberOfFaces);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteFontFile& WriteFontFile::Analyze(_Out_ BOOL& isSupportedFontType,_Out_ DWRITE_FONT_FILE_TYPE& fontFileType, _Out_ UINT32& numberOfFaces)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->Analyze(&isSupportedFontType,&fontFileType, nullptr, &numberOfFaces);
                CheckHRESULT(hr);
                return *this;
            }

            // ================================================================
            // WriteRenderingParams
            // ================================================================
            HWIN_EXPORT FLOAT WriteRenderingParams::GetGamma()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetGamma();
            }
            HWIN_EXPORT FLOAT WriteRenderingParams::GetEnhancedContrast()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetEnhancedContrast();
            }
            HWIN_EXPORT FLOAT WriteRenderingParams::GetClearTypeLevel()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetClearTypeLevel();
            }
            HWIN_EXPORT DWRITE_PIXEL_GEOMETRY WriteRenderingParams::GetPixelGeometry()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetPixelGeometry();
            }
            HWIN_EXPORT DWRITE_RENDERING_MODE WriteRenderingParams::GetRenderingMode()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetRenderingMode();
            }

            // ================================================================
            // WriteFontFace
            // ================================================================
            HWIN_EXPORT DWRITE_FONT_FACE_TYPE WriteFontFace::GetType()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetType();
            }
            HWIN_EXPORT WriteFontFace& WriteFontFace::GetFiles(_Inout_ UINT32* numberOfFiles, IDWriteFontFile** fontFiles)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFiles(numberOfFiles, fontFiles);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT UINT32 WriteFontFace::GetNumberOfFiles( )
            {
                UINT32 result;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFiles(&result, nullptr);
                CheckHRESULT(hr);
                return result;
            }

            HWIN_EXPORT std::shared_ptr< std::vector<WriteFontFile> > WriteFontFace::GetFiles( )
            {
                UINT32 numberOfFiles = GetNumberOfFiles( );
                IDWriteFontFile** fontFiles = reinterpret_cast<IDWriteFontFile**>(alloca(numberOfFiles*sizeof(IDWriteFontFile*)));

                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFiles(&numberOfFiles, fontFiles);
                CheckHRESULT(hr);

                std::shared_ptr< std::vector<WriteFontFile> > result = std::make_shared< std::vector<WriteFontFile> >(numberOfFiles);

                for (std::vector<WriteFontFile>::size_type i = 0; i < numberOfFiles; i++)
                {
                    IDWriteFontFile* fontFile = fontFiles[i];
                    WriteFontFile writeFontFile(fontFile);
                    result->push_back(writeFontFile);
                }

                return result;
            }

            HWIN_EXPORT UINT32 WriteFontFace::GetIndex()
            {
                UINT32 result;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFiles(&result, nullptr);
                CheckHRESULT(hr);
                return result;
            }

            HWIN_EXPORT DWRITE_FONT_SIMULATIONS WriteFontFace::GetSimulations()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetSimulations();
            }
            HWIN_EXPORT BOOL WriteFontFace::IsSymbolFont()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetSimulations();
            }
            HWIN_EXPORT WriteFontFace& WriteFontFace::GetMetrics(_Out_ DWRITE_FONT_METRICS* fontFaceMetrics)
            {
                CheckPointerNotNull(fontFaceMetrics);
                InterfaceType* pInterface = GetInterface();
                pInterface->GetMetrics(fontFaceMetrics);
                return *this;
            }
            HWIN_EXPORT WriteFontFace& WriteFontFace::GetMetrics(_Out_ DWRITE_FONT_METRICS& fontFaceMetrics)
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->GetMetrics(&fontFaceMetrics);
                return *this;
            }
            HWIN_EXPORT UINT16 WriteFontFace::GetGlyphCount()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetGlyphCount();
            }
            HWIN_EXPORT WriteFontFace& WriteFontFace::GetDesignGlyphMetrics(UINT16 const* glyphIndices, UINT32 glyphCount, DWRITE_GLYPH_METRICS* glyphMetrics, BOOL isSideways)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetDesignGlyphMetrics(glyphIndices, glyphCount, glyphMetrics, isSideways);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteFontFace& WriteFontFace::GetGlyphIndices(UINT32 const* codePoints, UINT32 codePointCount, UINT16* glyphIndices)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetGlyphIndices(codePoints, codePointCount, glyphIndices);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteFontFace& WriteFontFace::TryGetFontTable( _In_ UINT32 openTypeTableTag, const void** tableData, _Out_ UINT32* tableSize, _Out_ void** tableContext, _Out_ BOOL* exists)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->TryGetFontTable( openTypeTableTag, tableData, tableSize, tableContext, exists);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteFontFace& WriteFontFace::ReleaseFontTable(_In_ void* tableContext)
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->ReleaseFontTable(tableContext);
                return *this;
            }
            HWIN_EXPORT WriteFontFace& WriteFontFace::GetGlyphRunOutline(FLOAT emSize, UINT16 const* glyphIndices, FLOAT const* glyphAdvances, DWRITE_GLYPH_OFFSET const* glyphOffsets, UINT32 glyphCount, BOOL isSideways, BOOL isRightToLeft, IDWriteGeometrySink* geometrySink)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetGlyphRunOutline(emSize, glyphIndices, glyphAdvances, glyphOffsets, glyphCount, isSideways, isRightToLeft, geometrySink);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteFontFace& WriteFontFace::GetRecommendedRenderingMode(FLOAT emSize, FLOAT pixelsPerDip, DWRITE_MEASURING_MODE measuringMode, IDWriteRenderingParams* renderingParams, _Out_ DWRITE_RENDERING_MODE* renderingMode)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetRecommendedRenderingMode(emSize, pixelsPerDip, measuringMode, renderingParams, renderingMode);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT DWRITE_RENDERING_MODE WriteFontFace::GetRecommendedRenderingMode(FLOAT emSize, FLOAT pixelsPerDip, DWRITE_MEASURING_MODE measuringMode, IDWriteRenderingParams* renderingParams)
            {
                DWRITE_RENDERING_MODE result = DWRITE_RENDERING_MODE(0);
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetRecommendedRenderingMode(emSize, pixelsPerDip, measuringMode, renderingParams, &result);
                CheckHRESULT(hr);
                return result;
            }

            HWIN_EXPORT WriteFontFace& WriteFontFace::GetGdiCompatibleMetrics(FLOAT emSize,FLOAT pixelsPerDip,_In_opt_ DWRITE_MATRIX const* transform, _Out_ DWRITE_FONT_METRICS* fontFaceMetrics)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetGdiCompatibleMetrics(emSize,pixelsPerDip,transform, fontFaceMetrics);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteFontFace& WriteFontFace::GetGdiCompatibleGlyphMetrics( FLOAT emSize, FLOAT pixelsPerDip, _In_opt_ DWRITE_MATRIX const* transform, BOOL useGdiNatural, UINT16 const* glyphIndices, UINT32 glyphCount, DWRITE_GLYPH_METRICS* glyphMetrics, BOOL isSideways)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetGdiCompatibleGlyphMetrics( emSize, pixelsPerDip, transform, useGdiNatural, glyphIndices, glyphCount, glyphMetrics, isSideways);
                CheckHRESULT(hr);
                return *this;
            }

            // ================================================================
            // WriteFontCollectionLoader
            // ================================================================
            HWIN_EXPORT WriteFontCollectionLoader& WriteFontCollectionLoader::CreateEnumeratorFromKey(IDWriteFactory* factory,void const* collectionKey,UINT32 collectionKeySize, _Out_ IDWriteFontFileEnumerator** fontFileEnumerator)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateEnumeratorFromKey(factory,collectionKey,collectionKeySize, fontFileEnumerator);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteFontFileEnumerator WriteFontCollectionLoader::CreateEnumeratorFromKey(IDWriteFactory* factory,void const* collectionKey,UINT32 collectionKeySize)
            {
                IDWriteFontFileEnumerator* fontFileEnumerator;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateEnumeratorFromKey(factory,collectionKey,collectionKeySize, &fontFileEnumerator);
                CheckHRESULT(hr);
                WriteFontFileEnumerator result(fontFileEnumerator);
                return result;
            }

            // ================================================================
            // WriteFontFileEnumerator
            // ================================================================
            HWIN_EXPORT WriteFontFileEnumerator& WriteFontFileEnumerator::MoveNext(_Out_ BOOL* hasCurrentFile)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->MoveNext(hasCurrentFile);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT bool WriteFontFileEnumerator::MoveNext( )
            {
                BOOL hasCurrentFile;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->MoveNext(&hasCurrentFile);
                CheckHRESULT(hr);
                return hasCurrentFile != FALSE;
            }

            HWIN_EXPORT WriteFontFileEnumerator& WriteFontFileEnumerator::GetCurrentFontFile(_Out_ IDWriteFontFile** fontFile)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetCurrentFontFile(fontFile);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteFontFile WriteFontFileEnumerator::GetCurrentFontFile()
            {
                IDWriteFontFile* fontFile = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetCurrentFontFile(&fontFile);
                CheckHRESULT(hr);
                WriteFontFile result(fontFile);
                return result;
            }

            // ================================================================
            // WriteLocalizedStrings
            // ================================================================
            HWIN_EXPORT UINT32 WriteLocalizedStrings::GetCount()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetCount();
            }
            HWIN_EXPORT WriteLocalizedStrings& WriteLocalizedStrings::FindLocaleName(_In_z_ WCHAR const* localeName,_Out_ UINT32* index,_Out_ BOOL* exists)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->FindLocaleName(localeName,index,exists);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT bool WriteLocalizedStrings::FindLocaleName(_In_z_ WCHAR const* localeName,_Out_ UINT32* index)
            {
                BOOL exists = FALSE;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->FindLocaleName(localeName,index,&exists);
                CheckHRESULT(hr);
                return exists != FALSE;
            }
            HWIN_EXPORT WriteLocalizedStrings& WriteLocalizedStrings::GetLocaleNameLength(UINT32 index,_Out_ UINT32* length)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetLocaleNameLength(index,length);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT UINT32 WriteLocalizedStrings::GetLocaleNameLength(UINT32 index)
            {
                UINT32 result = 0;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetLocaleNameLength(index,&result);
                CheckHRESULT(hr);
                return result;
            }

            HWIN_EXPORT WriteLocalizedStrings& WriteLocalizedStrings::GetLocaleName(UINT32 index,WCHAR* localeName, UINT32 size)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetLocaleName(index,localeName, size);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT std::shared_ptr<String> WriteLocalizedStrings::GetLocaleName(UINT32 index)
            {
                UINT32 size = GetLocaleNameLength(index);
                std::shared_ptr<String> result = std::make_shared<String>(size,String::value_type(0));
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetLocaleName(index, const_cast<String::value_type*>( result->c_str() ), size);
                CheckHRESULT(hr);
                return result;
            }

            HWIN_EXPORT WriteLocalizedStrings& WriteLocalizedStrings::GetStringLength(UINT32 index,_Out_ UINT32* length)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetStringLength(index,length);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT UINT32 WriteLocalizedStrings::GetStringLength(UINT32 index)
            {
                UINT32 result = 0;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetStringLength(index,&result);
                CheckHRESULT(hr);
                return result;
            }

            HWIN_EXPORT WriteLocalizedStrings& WriteLocalizedStrings::GetString(UINT32 index,WCHAR* stringBuffer,UINT32 size)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetString(index,stringBuffer,size);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT std::shared_ptr<String> WriteLocalizedStrings::GetString(UINT32 index)
            {
                UINT32 size = GetStringLength(index);
                std::shared_ptr<String> result = std::make_shared<String>(size,String::value_type(0));
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetString(index, const_cast<String::value_type*>( result->c_str() ), size);
                CheckHRESULT(hr);
                return result;
            }

            // ================================================================
            // WriteFontCollection
            // ================================================================
            HWIN_EXPORT UINT32 WriteFontCollection::GetFontFamilyCount()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetFontFamilyCount();
            }

            HWIN_EXPORT WriteFontCollection& WriteFontCollection::GetFontFamily( UINT32 index, IDWriteFontFamily** fontFamily)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFontFamily( index, fontFamily);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteFontFamily WriteFontCollection::GetFontFamily( UINT32 index )
            {
                IDWriteFontFamily* fontFamily = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFontFamily( index, &fontFamily);
                CheckHRESULT(hr);
                WriteFontFamily result(fontFamily);
                return result;
            }
            HWIN_EXPORT std::shared_ptr< std::vector<WriteFontFamily> > WriteFontCollection::GetFontFamilies()
            {
                std::vector<WriteFontFamily>::size_type fontFamilyCount = GetFontFamilyCount();
                std::shared_ptr< std::vector<WriteFontFamily> > result = std::make_shared< std::vector<WriteFontFamily> >(fontFamilyCount);
                for(UINT32 i = 0; i < fontFamilyCount; i++)
                {
                    WriteFontFamily writeFontFamily = GetFontFamily( i );
                    result->push_back(writeFontFamily);
                }
                return result;
            }

            HWIN_EXPORT WriteFontCollection& WriteFontCollection::FindFamilyName(_In_z_ WCHAR const* familyName,_Out_ UINT32* index,_Out_ BOOL* exists)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->FindFamilyName(familyName,index,exists);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT bool WriteFontCollection::FindFamilyName(_In_z_ WCHAR const* familyName,_Out_ UINT32* index)
            {
                BOOL exists = FALSE;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->FindFamilyName(familyName,index,&exists);
                CheckHRESULT(hr);
                return exists != FALSE;
            }

            HWIN_EXPORT WriteFontCollection& WriteFontCollection::GetFontFromFontFace(IDWriteFontFace* fontFace,_Out_ IDWriteFont** font)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFontFromFontFace(fontFace,font);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteFont WriteFontCollection::GetFontFromFontFace(IDWriteFontFace* fontFace)
            {
                IDWriteFont* font = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFontFromFontFace(fontFace,&font);
                CheckHRESULT(hr);
                WriteFont result(font);
                return result;
            }

            // ================================================================
            // WriteFontList
            // ================================================================
            HWIN_EXPORT WriteFontList& WriteFontList::GetFontCollection(_Out_ IDWriteFontCollection** fontCollection)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFontCollection(fontCollection);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteFontCollection WriteFontList::GetFontCollection( )
            {
                IDWriteFontCollection* fontCollection = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFontCollection(&fontCollection);
                CheckHRESULT(hr);
                WriteFontCollection result(fontCollection);
                return result;
            }
            HWIN_EXPORT UINT32 WriteFontList::GetFontCount()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetFontCount();
            }
            HWIN_EXPORT WriteFontList& WriteFontList::GetFont(UINT32 index, _Out_ IDWriteFont** font)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFont(index, font);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteFont WriteFontList::GetFont(UINT32 index)
            {
                IDWriteFont* font;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFont(index, &font);
                CheckHRESULT(hr);
                WriteFont result(font);
                return result;
            }
            // ================================================================
            // WriteFontFamily
            // ================================================================
            HWIN_EXPORT WriteFontFamily& WriteFontFamily::GetFamilyNames(_Out_ IDWriteLocalizedStrings** names)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFamilyNames(names);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteLocalizedStrings WriteFontFamily::GetFamilyNames( )
            {
                IDWriteLocalizedStrings* names = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFamilyNames(&names);
                CheckHRESULT(hr);
                WriteLocalizedStrings result(names);
                return result;
            }
            HWIN_EXPORT WriteFontFamily& WriteFontFamily::GetFirstMatchingFont(DWRITE_FONT_WEIGHT  weight,DWRITE_FONT_STRETCH stretch,DWRITE_FONT_STYLE style,_Out_ IDWriteFont** matchingFont)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFirstMatchingFont(weight,stretch,style,matchingFont);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteFont WriteFontFamily::GetFirstMatchingFont(DWRITE_FONT_WEIGHT  weight,DWRITE_FONT_STRETCH stretch,DWRITE_FONT_STYLE style)
            {
                IDWriteFont* matchingFont = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFirstMatchingFont(weight,stretch,style,&matchingFont);
                CheckHRESULT(hr);
                WriteFont result(matchingFont);
                return result;
            }
            HWIN_EXPORT WriteFontFamily& WriteFontFamily::GetMatchingFonts(DWRITE_FONT_WEIGHT weight,DWRITE_FONT_STRETCH stretch,DWRITE_FONT_STYLE style,_Out_ IDWriteFontList** matchingFonts)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetMatchingFonts(weight,stretch,style,matchingFonts);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteFontList WriteFontFamily::GetMatchingFonts(DWRITE_FONT_WEIGHT weight,DWRITE_FONT_STRETCH stretch,DWRITE_FONT_STYLE style)
            {
                IDWriteFontList* matchingFonts = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetMatchingFonts(weight,stretch,style,&matchingFonts);
                CheckHRESULT(hr);
                WriteFontList result(matchingFonts);
                return result;
            }

            // ================================================================
            // WriteFont
            // ================================================================
            HWIN_EXPORT WriteFont& WriteFont::GetFontFamily(_Out_ IDWriteFontFamily** fontFamily)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFontFamily(fontFamily);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteFontFamily WriteFont::GetFontFamily( )
            {
                IDWriteFontFamily* fontFamily = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFontFamily(&fontFamily);
                CheckHRESULT(hr);
                WriteFontFamily result(fontFamily);
                return result;
            }
            HWIN_EXPORT DWRITE_FONT_WEIGHT WriteFont::GetWeight()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetWeight();
            }
            HWIN_EXPORT DWRITE_FONT_STRETCH WriteFont::GetStretch()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetStretch();
            }
            HWIN_EXPORT DWRITE_FONT_STYLE WriteFont::GetStyle()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetStyle();
            }
            HWIN_EXPORT bool WriteFont::IsSymbolFont()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->IsSymbolFont() != FALSE;
            }
            HWIN_EXPORT WriteFont& WriteFont::GetFaceNames(_Out_ IDWriteLocalizedStrings** names)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFaceNames(names);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteLocalizedStrings WriteFont::GetFaceNames()
            {
                IDWriteLocalizedStrings* names = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFaceNames(&names);
                CheckHRESULT(hr);
                WriteLocalizedStrings result(names);
                return result;
            }
            HWIN_EXPORT WriteFont& WriteFont::GetInformationalStrings(DWRITE_INFORMATIONAL_STRING_ID informationalStringID,_Out_ IDWriteLocalizedStrings** informationalStrings,_Out_ BOOL* exists)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetInformationalStrings(informationalStringID,informationalStrings,exists);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT DWRITE_FONT_SIMULATIONS WriteFont::GetSimulations()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetSimulations();
            }
            HWIN_EXPORT WriteFont& WriteFont::GetMetrics(_Out_ DWRITE_FONT_METRICS* fontMetrics)
            {
                InterfaceType* pInterface = GetInterface();
                pInterface->GetMetrics(fontMetrics);
                return *this;
            }
            HWIN_EXPORT WriteFont& WriteFont::HasCharacter(UINT32 unicodeValue,_Out_ BOOL* exists)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->HasCharacter(unicodeValue,exists);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT bool WriteFont::HasCharacter(UINT32 unicodeValue)
            {
                BOOL exists = FALSE;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->HasCharacter(unicodeValue,&exists);
                CheckHRESULT(hr);
                return exists != FALSE;
            }
            HWIN_EXPORT WriteFont& WriteFont::CreateFontFace(_Out_ IDWriteFontFace** fontFace)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateFontFace(fontFace);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteFontFace WriteFont::CreateFontFace( )
            {
                IDWriteFontFace* fontFace = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateFontFace(&fontFace);
                CheckHRESULT(hr);
                WriteFontFace result(fontFace);
                return result;
            }
            // ================================================================
            // WriteTextFormat
            // ================================================================
            HWIN_EXPORT WriteTextFormat& WriteTextFormat::SetTextAlignment(DWRITE_TEXT_ALIGNMENT textAlignment)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->SetTextAlignment(textAlignment);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteTextFormat& WriteTextFormat::SetParagraphAlignment(DWRITE_PARAGRAPH_ALIGNMENT paragraphAlignment)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->SetParagraphAlignment(paragraphAlignment);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteTextFormat& WriteTextFormat::SetWordWrapping(DWRITE_WORD_WRAPPING wordWrapping)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->SetWordWrapping(wordWrapping);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteTextFormat& WriteTextFormat::SetReadingDirection(DWRITE_READING_DIRECTION readingDirection)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->SetReadingDirection(readingDirection);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteTextFormat& WriteTextFormat::SetFlowDirection(DWRITE_FLOW_DIRECTION flowDirection)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->SetFlowDirection(flowDirection);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteTextFormat& WriteTextFormat::SetIncrementalTabStop(FLOAT incrementalTabStop)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->SetIncrementalTabStop(incrementalTabStop);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteTextFormat& WriteTextFormat::SetTrimming(_In_ DWRITE_TRIMMING const* trimmingOptions,IDWriteInlineObject* trimmingSign)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->SetTrimming(trimmingOptions,trimmingSign);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteTextFormat& WriteTextFormat::SetLineSpacing(DWRITE_LINE_SPACING_METHOD lineSpacingMethod,FLOAT lineSpacing,FLOAT baseline)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->SetLineSpacing(lineSpacingMethod,lineSpacing,baseline);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT DWRITE_TEXT_ALIGNMENT WriteTextFormat::GetTextAlignment()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetTextAlignment();
            }
            HWIN_EXPORT DWRITE_PARAGRAPH_ALIGNMENT WriteTextFormat::GetParagraphAlignment()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetParagraphAlignment();
            }
            HWIN_EXPORT DWRITE_WORD_WRAPPING WriteTextFormat::GetWordWrapping()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetWordWrapping();
            }
            HWIN_EXPORT DWRITE_READING_DIRECTION WriteTextFormat::GetReadingDirection()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetReadingDirection();
            }
            HWIN_EXPORT DWRITE_FLOW_DIRECTION WriteTextFormat::GetFlowDirection()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetFlowDirection();
            }
            HWIN_EXPORT FLOAT WriteTextFormat::GetIncrementalTabStop()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetIncrementalTabStop();
            }
            HWIN_EXPORT WriteTextFormat& WriteTextFormat::GetTrimming(_Out_ DWRITE_TRIMMING* trimmingOptions,_Out_ IDWriteInlineObject** trimmingSign)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetTrimming(trimmingOptions,trimmingSign);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteInlineObject WriteTextFormat::GetTrimming(_Out_ DWRITE_TRIMMING& trimmingOptions)
            {
                IDWriteInlineObject* trimmingSign = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetTrimming(&trimmingOptions,&trimmingSign);
                CheckHRESULT(hr);
                WriteInlineObject result(trimmingSign);
                return result;
            }
            HWIN_EXPORT WriteTextFormat& WriteTextFormat::GetLineSpacing(_Out_ DWRITE_LINE_SPACING_METHOD* lineSpacingMethod,_Out_ FLOAT* lineSpacing,_Out_ FLOAT* baseline)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetLineSpacing(lineSpacingMethod,lineSpacing,baseline);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteTextFormat& WriteTextFormat::GetFontCollection(_Out_ IDWriteFontCollection** fontCollection)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFontCollection(fontCollection);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteFontCollection WriteTextFormat::GetFontCollection( )
            {
                IDWriteFontCollection* fontCollection = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFontCollection(&fontCollection);
                CheckHRESULT(hr);
                WriteFontCollection result(fontCollection);
                return result;
            }

            HWIN_EXPORT UINT32 WriteTextFormat::GetFontFamilyNameLength()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetFontFamilyNameLength();
            }
            HWIN_EXPORT WriteTextFormat& WriteTextFormat::GetFontFamilyName(WCHAR* fontFamilyName,UINT32 nameSize)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFontFamilyName(fontFamilyName,nameSize);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT std::shared_ptr<String> WriteTextFormat::GetFontFamilyName( )
            {
                UINT32 nameSize = GetFontFamilyNameLength();
                std::shared_ptr<String> result = std::make_shared<String>(nameSize,String::value_type(0));
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFontFamilyName(const_cast<wchar_t*>(result->c_str()),nameSize);
                CheckHRESULT(hr);
                return result;
            }
            HWIN_EXPORT DWRITE_FONT_WEIGHT WriteTextFormat::GetFontWeight()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetFontWeight();
            }
            HWIN_EXPORT DWRITE_FONT_STYLE WriteTextFormat::GetFontStyle()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetFontStyle();
            }
            HWIN_EXPORT DWRITE_FONT_STRETCH WriteTextFormat::GetFontStretch()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetFontStretch();
            }
            HWIN_EXPORT FLOAT WriteTextFormat::GetFontSize()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetFontSize();
            }
            HWIN_EXPORT UINT32 WriteTextFormat::GetLocaleNameLength()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetLocaleNameLength();
            }
            HWIN_EXPORT WriteTextFormat& WriteTextFormat::GetLocaleName(WCHAR* localeName,UINT32 nameSize)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetLocaleName(localeName,nameSize);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT std::shared_ptr<String> WriteTextFormat::GetLocaleName( )
            {
                UINT32 nameSize = GetLocaleNameLength();
                std::shared_ptr<String> result = std::make_shared<String>(nameSize,String::value_type(0));
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetLocaleName(const_cast<wchar_t*>(result->c_str()),nameSize);
                CheckHRESULT(hr);
                return result;
            }
            // ================================================================
            // WriteTypography
            // ================================================================
            HWIN_EXPORT WriteTypography& WriteTypography::AddFontFeature(DWRITE_FONT_FEATURE fontFeature)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->AddFontFeature(fontFeature);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteTypography& WriteTypography::AddFontFeatures(std::shared_ptr< std::vector<DWRITE_FONT_FEATURE> > fontFeatures)
            {
                const std::vector<DWRITE_FONT_FEATURE>& elements = *fontFeatures.get();
                for(DWRITE_FONT_FEATURE fontFeature : elements)
                {
                    AddFontFeature(fontFeature);
                }
                return *this;
            }
            HWIN_EXPORT UINT32 WriteTypography::GetFontFeatureCount()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetFontFeatureCount();
            }
            HWIN_EXPORT WriteTypography& WriteTypography::GetFontFeature(UINT32 fontFeatureIndex,_Out_ DWRITE_FONT_FEATURE* fontFeature)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFontFeature(fontFeatureIndex,fontFeature);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT DWRITE_FONT_FEATURE WriteTypography::GetFontFeature(UINT32 fontFeatureIndex)
            {
                DWRITE_FONT_FEATURE fontFeature;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFontFeature(fontFeatureIndex,&fontFeature);
                CheckHRESULT(hr);
                return fontFeature;
            }
            HWIN_EXPORT std::shared_ptr< std::vector<DWRITE_FONT_FEATURE> > WriteTypography::GetFontFeatures( )
            {
                std::vector<DWRITE_FONT_FEATURE>::size_type fontFeatureCount = GetFontFeatureCount();
                std::shared_ptr< std::vector<DWRITE_FONT_FEATURE> > result = std::make_shared< std::vector<DWRITE_FONT_FEATURE> >(fontFeatureCount);
                for(UINT32 i = 0; i < fontFeatureCount; i++)
                {
                    DWRITE_FONT_FEATURE fontFeature = GetFontFeature(i);
                    result->push_back(fontFeature);
                }
                return result;
            }

            // ================================================================
            // WriteTextAnalysisSource
            // ================================================================
            HWIN_EXPORT WriteTextAnalysisSource& WriteTextAnalysisSource::GetTextAtPosition(UINT32 textPosition,WCHAR const** textString,_Out_ UINT32* textLength)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetTextAtPosition(textPosition,textString,textLength);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteTextAnalysisSource& WriteTextAnalysisSource::GetTextBeforePosition(UINT32 textPosition,WCHAR const** textString,_Out_ UINT32* textLength)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetTextBeforePosition(textPosition,textString,textLength);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT DWRITE_READING_DIRECTION WriteTextAnalysisSource::GetParagraphReadingDirection()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetParagraphReadingDirection();
            }
            HWIN_EXPORT WriteTextAnalysisSource& WriteTextAnalysisSource::GetLocaleName(UINT32 textPosition,_Out_ UINT32* textLength, _Outptr_result_z_ WCHAR const** localeName)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetLocaleName(textPosition,textLength, localeName);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteTextAnalysisSource& WriteTextAnalysisSource::GetNumberSubstitution(UINT32 textPosition,_Out_ UINT32* textLength,_Outptr_ IDWriteNumberSubstitution** numberSubstitution)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetNumberSubstitution(textPosition,textLength,numberSubstitution);
                CheckHRESULT(hr);
                return *this;
            }

            // ================================================================
            // WriteTextAnalysisSink
            // ================================================================
            HWIN_EXPORT WriteTextAnalysisSink& WriteTextAnalysisSink::SetScriptAnalysis(UINT32 textPosition,UINT32 textLength,_In_ DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->SetScriptAnalysis(textPosition,textLength,scriptAnalysis);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteTextAnalysisSink& WriteTextAnalysisSink::SetLineBreakpoints(UINT32 textPosition,UINT32 textLength,DWRITE_LINE_BREAKPOINT const* lineBreakpoints)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->SetLineBreakpoints(textPosition,textLength,lineBreakpoints);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteTextAnalysisSink& WriteTextAnalysisSink::SetBidiLevel(UINT32 textPosition,UINT32 textLength,UINT8 explicitLevel,UINT8 resolvedLevel)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->SetBidiLevel(textPosition,textLength,explicitLevel,resolvedLevel);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteTextAnalysisSink& WriteTextAnalysisSink::SetNumberSubstitution(UINT32 textPosition,UINT32 textLength,_In_ IDWriteNumberSubstitution* numberSubstitution)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->SetNumberSubstitution(textPosition,textLength,numberSubstitution);
                CheckHRESULT(hr);
                return *this;
            }
            // ================================================================
            // WriteTextAnalyzer
            // ================================================================
            HWIN_EXPORT WriteTextAnalyzer& WriteTextAnalyzer::AnalyzeScript(
                IDWriteTextAnalysisSource* analysisSource,
                UINT32 textPosition,
                UINT32 textLength,
                IDWriteTextAnalysisSink* analysisSink)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->AnalyzeScript(analysisSource,textPosition,textLength,analysisSink);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextAnalyzer& WriteTextAnalyzer::AnalyzeBidi(
                IDWriteTextAnalysisSource* analysisSource,
                UINT32 textPosition,
                UINT32 textLength,
                IDWriteTextAnalysisSink* analysisSink)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->AnalyzeBidi(analysisSource,textPosition,textLength,analysisSink);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextAnalyzer& WriteTextAnalyzer::AnalyzeNumberSubstitution(
                IDWriteTextAnalysisSource* analysisSource,
                UINT32 textPosition,
                UINT32 textLength,
                IDWriteTextAnalysisSink* analysisSink)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->AnalyzeNumberSubstitution(analysisSource,textPosition,textLength,analysisSink);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextAnalyzer& WriteTextAnalyzer::AnalyzeLineBreakpoints(
                IDWriteTextAnalysisSource* analysisSource,
                UINT32 textPosition,
                UINT32 textLength,
                IDWriteTextAnalysisSink* analysisSink)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->AnalyzeLineBreakpoints(analysisSource,textPosition,textLength,analysisSink);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextAnalyzer& WriteTextAnalyzer::GetGlyphs(
                WCHAR const* textString,
                UINT32 textLength,
                IDWriteFontFace* fontFace,
                BOOL isSideways,
                BOOL isRightToLeft,
                _In_ DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis,
                _In_opt_z_ WCHAR const* localeName,
                _In_opt_ IDWriteNumberSubstitution* numberSubstitution,
                DWRITE_TYPOGRAPHIC_FEATURES const** features,
                UINT32 const* featureRangeLengths,
                UINT32 featureRanges,
                UINT32 maxGlyphCount,
                UINT16* clusterMap,
                DWRITE_SHAPING_TEXT_PROPERTIES* textProps,
                UINT16* glyphIndices,
                DWRITE_SHAPING_GLYPH_PROPERTIES* glyphProps,
                _Out_ UINT32* actualGlyphCount)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetGlyphs(textString,textLength,fontFace,isSideways,isRightToLeft,scriptAnalysis,localeName,numberSubstitution,features,featureRangeLengths,featureRanges,maxGlyphCount,clusterMap,textProps,glyphIndices,glyphProps,actualGlyphCount);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextAnalyzer& WriteTextAnalyzer::GetGlyphPlacements(
                WCHAR const* textString,
                UINT16 const* clusterMap,
                DWRITE_SHAPING_TEXT_PROPERTIES* textProps,
                UINT32 textLength,
                UINT16 const* glyphIndices,
                DWRITE_SHAPING_GLYPH_PROPERTIES const* glyphProps,
                UINT32 glyphCount,
                IDWriteFontFace * fontFace,
                FLOAT fontEmSize,
                BOOL isSideways,
                BOOL isRightToLeft,
                _In_ DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis,
                _In_opt_z_ WCHAR const* localeName,
                DWRITE_TYPOGRAPHIC_FEATURES const** features,
                UINT32 const* featureRangeLengths,
                UINT32 featureRanges,
                FLOAT* glyphAdvances,
                DWRITE_GLYPH_OFFSET* glyphOffsets)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetGlyphPlacements(textString,clusterMap,textProps,textLength,glyphIndices,glyphProps,glyphCount,fontFace,fontEmSize,isSideways,isRightToLeft,scriptAnalysis,localeName,features,featureRangeLengths,featureRanges,glyphAdvances,glyphOffsets);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextAnalyzer& WriteTextAnalyzer::GetGdiCompatibleGlyphPlacements(
                WCHAR const* textString,
                UINT16 const* clusterMap,
                DWRITE_SHAPING_TEXT_PROPERTIES* textProps,
                UINT32 textLength,
                UINT16 const* glyphIndices,
                DWRITE_SHAPING_GLYPH_PROPERTIES const* glyphProps,
                UINT32 glyphCount,
                IDWriteFontFace * fontFace,
                FLOAT fontEmSize,
                FLOAT pixelsPerDip,
                _In_opt_ DWRITE_MATRIX const* transform,
                BOOL useGdiNatural,
                BOOL isSideways,
                BOOL isRightToLeft,
                _In_ DWRITE_SCRIPT_ANALYSIS const* scriptAnalysis,
                _In_opt_z_ WCHAR const* localeName,
                DWRITE_TYPOGRAPHIC_FEATURES const** features,
                UINT32 const* featureRangeLengths,
                UINT32 featureRanges,
                FLOAT* glyphAdvances,
                DWRITE_GLYPH_OFFSET* glyphOffsets)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetGdiCompatibleGlyphPlacements(textString,clusterMap,textProps,textLength,glyphIndices,glyphProps,glyphCount,fontFace,fontEmSize,pixelsPerDip,transform,useGdiNatural,isSideways,isRightToLeft,scriptAnalysis,localeName,features,featureRangeLengths,featureRanges,glyphAdvances,glyphOffsets);
                CheckHRESULT(hr);
                return *this;
            }


            // ================================================================
            // WriteInlineObject
            // ================================================================
            HWIN_EXPORT WriteInlineObject& WriteInlineObject::Draw(_In_opt_ void* clientDrawingContext,IDWriteTextRenderer* renderer,FLOAT originX,FLOAT originY,BOOL isSideways,BOOL isRightToLeft,_In_opt_ IUnknown* clientDrawingEffect)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->Draw(clientDrawingContext,renderer,originX,originY,isSideways,isRightToLeft,clientDrawingEffect);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteInlineObject& WriteInlineObject::GetMetrics(_Out_ DWRITE_INLINE_OBJECT_METRICS* metrics)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetMetrics(metrics);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteInlineObject& WriteInlineObject::GetOverhangMetrics(_Out_ DWRITE_OVERHANG_METRICS* overhangs)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetOverhangMetrics(overhangs);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteInlineObject& WriteInlineObject::GetBreakConditions(_Out_ DWRITE_BREAK_CONDITION* breakConditionBefore,_Out_ DWRITE_BREAK_CONDITION* breakConditionAfter)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetBreakConditions(breakConditionBefore,breakConditionAfter);
                CheckHRESULT(hr);
                return *this;
            }

            // ================================================================
            // WritePixelSnapping
            // ================================================================
            HWIN_EXPORT WritePixelSnapping& WritePixelSnapping::IsPixelSnappingDisabled(_In_opt_ void* clientDrawingContext,_Out_ BOOL* isDisabled)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->IsPixelSnappingDisabled(clientDrawingContext,isDisabled);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WritePixelSnapping& WritePixelSnapping::GetCurrentTransform(_In_opt_ void* clientDrawingContext,_Out_ DWRITE_MATRIX* transform)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetCurrentTransform(clientDrawingContext,transform);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WritePixelSnapping& WritePixelSnapping::GetPixelsPerDip(_In_opt_ void* clientDrawingContext,_Out_ FLOAT* pixelsPerDip)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetPixelsPerDip(clientDrawingContext,pixelsPerDip);
                CheckHRESULT(hr);
                return *this;
            }

            // ================================================================
            // WriteTextRenderer
            // ================================================================
            HWIN_EXPORT WriteTextRenderer& WriteTextRenderer::DrawGlyphRun(_In_opt_ void* clientDrawingContext,FLOAT baselineOriginX,FLOAT baselineOriginY,DWRITE_MEASURING_MODE measuringMode,_In_ DWRITE_GLYPH_RUN const* glyphRun,_In_ DWRITE_GLYPH_RUN_DESCRIPTION const* glyphRunDescription,_In_opt_ IUnknown* clientDrawingEffect)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->DrawGlyphRun(clientDrawingContext,baselineOriginX,baselineOriginY,measuringMode,glyphRun,glyphRunDescription,clientDrawingEffect);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteTextRenderer& WriteTextRenderer::DrawUnderline(_In_opt_ void* clientDrawingContext,FLOAT baselineOriginX,FLOAT baselineOriginY,_In_ DWRITE_UNDERLINE const* underline,_In_opt_ IUnknown* clientDrawingEffect)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->DrawUnderline(clientDrawingContext,baselineOriginX,baselineOriginY,underline,clientDrawingEffect);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteTextRenderer& WriteTextRenderer::DrawStrikethrough(_In_opt_ void* clientDrawingContext,FLOAT baselineOriginX,FLOAT baselineOriginY,_In_ DWRITE_STRIKETHROUGH const* strikethrough,_In_opt_ IUnknown* clientDrawingEffect)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->DrawStrikethrough(clientDrawingContext,baselineOriginX,baselineOriginY,strikethrough,clientDrawingEffect);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteTextRenderer& WriteTextRenderer::DrawInlineObject(_In_opt_ void* clientDrawingContext,FLOAT originX,FLOAT originY,IDWriteInlineObject* inlineObject,BOOL isSideways,BOOL isRightToLeft,_In_opt_ IUnknown* clientDrawingEffect)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->DrawInlineObject(clientDrawingContext,originX,originY,inlineObject,isSideways,isRightToLeft,clientDrawingEffect);
                CheckHRESULT(hr);
                return *this;
            }
            // ================================================================
            // 
            // ================================================================
            HWIN_EXPORT WriteTextLayout& WriteTextLayout::SetMaxWidth(FLOAT maxWidth)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->SetMaxWidth(maxWidth);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteTextLayout& WriteTextLayout::SetMaxHeight(FLOAT maxHeight)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->SetMaxHeight(maxHeight);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextLayout& WriteTextLayout::SetFontCollection(IDWriteFontCollection* fontCollection,DWRITE_TEXT_RANGE textRange)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->SetFontCollection(fontCollection,textRange);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextLayout& WriteTextLayout::SetFontFamilyName(_In_z_ WCHAR const* fontFamilyName,DWRITE_TEXT_RANGE textRange)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->SetFontFamilyName(fontFamilyName,textRange);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextLayout& WriteTextLayout::SetFontWeight(DWRITE_FONT_WEIGHT fontWeight,DWRITE_TEXT_RANGE textRange)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->SetFontWeight(fontWeight,textRange);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextLayout& WriteTextLayout::SetFontStyle(DWRITE_FONT_STYLE fontStyle,DWRITE_TEXT_RANGE textRange)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->SetFontStyle(fontStyle,textRange);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextLayout& WriteTextLayout::SetFontStretch(DWRITE_FONT_STRETCH fontStretch,DWRITE_TEXT_RANGE textRange)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->SetFontStretch(fontStretch,textRange);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextLayout& WriteTextLayout::SetFontSize(FLOAT fontSize,DWRITE_TEXT_RANGE textRange)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->SetFontSize(fontSize,textRange);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextLayout& WriteTextLayout::SetUnderline(BOOL hasUnderline,DWRITE_TEXT_RANGE textRange)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->SetUnderline(hasUnderline,textRange);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextLayout& WriteTextLayout::SetStrikethrough(BOOL hasStrikethrough,DWRITE_TEXT_RANGE textRange)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->SetStrikethrough(hasStrikethrough,textRange);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextLayout& WriteTextLayout::SetDrawingEffect(IUnknown* drawingEffect,DWRITE_TEXT_RANGE textRange)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->SetDrawingEffect(drawingEffect,textRange);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteTextLayout& WriteTextLayout::SetInlineObject(IDWriteInlineObject* inlineObject,DWRITE_TEXT_RANGE textRange)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->SetInlineObject(inlineObject,textRange);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextLayout& WriteTextLayout::SetTypography(IDWriteTypography* typography,DWRITE_TEXT_RANGE textRange)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->SetTypography(typography,textRange);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextLayout& WriteTextLayout::SetLocaleName(_In_z_ WCHAR const* localeName,DWRITE_TEXT_RANGE textRange)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->SetLocaleName(localeName,textRange);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT FLOAT WriteTextLayout::GetMaxWidth()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetMaxWidth();
            }

            HWIN_EXPORT FLOAT WriteTextLayout::GetMaxHeight()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetMaxHeight();
            }

            HWIN_EXPORT WriteTextLayout& WriteTextLayout::GetFontCollection(UINT32 currentPosition,_Out_ IDWriteFontCollection** fontCollection,_Out_opt_ DWRITE_TEXT_RANGE* textRange)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFontCollection(currentPosition,fontCollection,textRange);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextLayout& WriteTextLayout::GetFontFamilyNameLength(UINT32 currentPosition,_Out_ UINT32* nameLength,_Out_opt_ DWRITE_TEXT_RANGE* textRange )
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFontFamilyNameLength(currentPosition,nameLength,textRange );
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextLayout& WriteTextLayout::GetFontFamilyName(UINT32 currentPosition,_Out_writes_z_(nameSize) WCHAR* fontFamilyName,UINT32 nameSize,_Out_opt_ DWRITE_TEXT_RANGE* textRange)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFontFamilyName(currentPosition,fontFamilyName,nameSize,textRange);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteTextLayout& WriteTextLayout::GetFontWeight(UINT32 currentPosition,_Out_ DWRITE_FONT_WEIGHT* fontWeight,_Out_opt_ DWRITE_TEXT_RANGE* textRange )
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFontWeight(currentPosition,fontWeight,textRange );
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteTextLayout& WriteTextLayout::GetFontStyle(UINT32 currentPosition,_Out_ DWRITE_FONT_STYLE* fontStyle,_Out_opt_ DWRITE_TEXT_RANGE* textRange )
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFontStyle(currentPosition,fontStyle,textRange );
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextLayout& WriteTextLayout::GetFontStretch(UINT32 currentPosition,_Out_ DWRITE_FONT_STRETCH* fontStretch,_Out_opt_ DWRITE_TEXT_RANGE* textRange)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFontStretch(currentPosition,fontStretch,textRange);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextLayout& WriteTextLayout::GetFontSize(UINT32 currentPosition,_Out_ FLOAT* fontSize,_Out_opt_ DWRITE_TEXT_RANGE* textRange )
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetFontSize(currentPosition,fontSize,textRange );
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextLayout& WriteTextLayout::GetUnderline(UINT32 currentPosition,_Out_ BOOL* hasUnderline,_Out_opt_ DWRITE_TEXT_RANGE* textRange )
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetUnderline(currentPosition,hasUnderline,textRange );
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextLayout& WriteTextLayout::GetStrikethrough(UINT32 currentPosition,_Out_ BOOL* hasStrikethrough,_Out_opt_ DWRITE_TEXT_RANGE* textRange )
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetStrikethrough(currentPosition,hasStrikethrough,textRange );
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextLayout& WriteTextLayout::GetDrawingEffect(UINT32 currentPosition,_Out_ IUnknown** drawingEffect,_Out_opt_ DWRITE_TEXT_RANGE* textRange )
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetDrawingEffect(currentPosition,drawingEffect,textRange );
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteTextLayout& WriteTextLayout::GetInlineObject(UINT32 currentPosition,_Out_ IDWriteInlineObject** inlineObject,_Out_opt_ DWRITE_TEXT_RANGE* textRange )
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetInlineObject(currentPosition,inlineObject,textRange );
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteTextLayout& WriteTextLayout::GetTypography(UINT32 currentPosition,_Out_ IDWriteTypography** typography,_Out_opt_ DWRITE_TEXT_RANGE* textRange )
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetTypography(currentPosition,typography,textRange );
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextLayout& WriteTextLayout::GetLocaleNameLength(UINT32 currentPosition,_Out_ UINT32* nameLength,_Out_opt_ DWRITE_TEXT_RANGE* textRange )
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetLocaleNameLength(currentPosition,nameLength,textRange );
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextLayout& WriteTextLayout::GetLocaleName(UINT32 currentPosition,_Out_writes_z_(nameSize) WCHAR* localeName,UINT32 nameSize,_Out_opt_ DWRITE_TEXT_RANGE* textRange )
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetLocaleName(currentPosition,localeName,nameSize,textRange );
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextLayout& WriteTextLayout::Draw(_In_opt_ void* clientDrawingContext,IDWriteTextRenderer* renderer,FLOAT originX,FLOAT originY)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->Draw(clientDrawingContext,renderer,originX,originY);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextLayout& WriteTextLayout::GetLineMetrics(DWRITE_LINE_METRICS* lineMetrics,UINT32 maxLineCount,_Out_ UINT32* actualLineCount)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetLineMetrics(lineMetrics,maxLineCount,actualLineCount);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextLayout& WriteTextLayout::GetMetrics(_Out_ DWRITE_TEXT_METRICS* textMetrics)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetMetrics(textMetrics);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextLayout& WriteTextLayout::GetOverhangMetrics(_Out_ DWRITE_OVERHANG_METRICS* overhangs)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetOverhangMetrics(overhangs);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextLayout& WriteTextLayout::GetClusterMetrics(DWRITE_CLUSTER_METRICS* clusterMetrics,UINT32 maxClusterCount,_Out_ UINT32* actualClusterCount)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetClusterMetrics(clusterMetrics,maxClusterCount,actualClusterCount);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextLayout& WriteTextLayout::DetermineMinWidth(_Out_ FLOAT* minWidth)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->DetermineMinWidth(minWidth);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextLayout& WriteTextLayout::HitTestPoint(FLOAT pointX,FLOAT pointY,_Out_ BOOL* isTrailingHit,_Out_ BOOL* isInside,_Out_ DWRITE_HIT_TEST_METRICS* hitTestMetrics)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->HitTestPoint(pointX,pointY,isTrailingHit,isInside,hitTestMetrics);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTextLayout& WriteTextLayout::HitTestTextPosition(UINT32 textPosition,BOOL isTrailingHit,_Out_ FLOAT* pointX,_Out_ FLOAT* pointY,_Out_ DWRITE_HIT_TEST_METRICS* hitTestMetrics)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->HitTestTextPosition(textPosition,isTrailingHit,pointX,pointY,hitTestMetrics);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteTextLayout& WriteTextLayout::HitTestTextRange(UINT32 textPosition,UINT32 textLength,FLOAT originX,FLOAT originY,DWRITE_HIT_TEST_METRICS* hitTestMetrics,UINT32 maxHitTestMetricsCount,_Out_ UINT32* actualHitTestMetricsCount)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->HitTestTextRange(textPosition,textLength,originX,originY,hitTestMetrics,maxHitTestMetricsCount,actualHitTestMetricsCount);
                CheckHRESULT(hr);
                return *this;
            }

            // ================================================================
            // WriteBitmapRenderTarget
            // ================================================================
            HWIN_EXPORT WriteBitmapRenderTarget& WriteBitmapRenderTarget::DrawGlyphRun(FLOAT baselineOriginX,FLOAT baselineOriginY,DWRITE_MEASURING_MODE measuringMode,_In_ DWRITE_GLYPH_RUN const* glyphRun,IDWriteRenderingParams* renderingParams,COLORREF textColor,_Out_opt_ RECT* blackBoxRect)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->DrawGlyphRun(baselineOriginX,baselineOriginY,measuringMode,glyphRun,renderingParams,textColor,blackBoxRect);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT HDC WriteBitmapRenderTarget::GetMemoryDC()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetMemoryDC();
            }

            HWIN_EXPORT FLOAT WriteBitmapRenderTarget::GetPixelsPerDip()
            {
                InterfaceType* pInterface = GetInterface();
                return pInterface->GetPixelsPerDip();
            }
            HWIN_EXPORT WriteBitmapRenderTarget& WriteBitmapRenderTarget::SetPixelsPerDip(FLOAT pixelsPerDip)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->SetPixelsPerDip(pixelsPerDip);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteBitmapRenderTarget& WriteBitmapRenderTarget::GetCurrentTransform(_Out_ DWRITE_MATRIX* transform)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetCurrentTransform(transform);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteBitmapRenderTarget& WriteBitmapRenderTarget::SetCurrentTransform(_In_opt_ DWRITE_MATRIX const* transform)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->SetCurrentTransform(transform);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteBitmapRenderTarget& WriteBitmapRenderTarget::GetSize(_Out_ SIZE* size)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetSize(size);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteBitmapRenderTarget& WriteBitmapRenderTarget::Resize(UINT32 width,UINT32 height)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->Resize(width,height);
                CheckHRESULT(hr);
                return *this;
            }
            // ================================================================
            // WriteGdiInterop
            // ================================================================
            HWIN_EXPORT WriteGdiInterop& WriteGdiInterop::CreateFontFromLOGFONT(_In_ LOGFONTW const* logFont,_Out_ IDWriteFont** font)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateFontFromLOGFONT(logFont,font);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteGdiInterop& WriteGdiInterop::ConvertFontToLOGFONT(IDWriteFont* font,_Out_ LOGFONTW* logFont,_Out_ BOOL* isSystemFont)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->ConvertFontToLOGFONT(font,logFont,isSystemFont);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteGdiInterop& WriteGdiInterop::ConvertFontFaceToLOGFONT(IDWriteFontFace* font,_Out_ LOGFONTW* logFont)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->ConvertFontFaceToLOGFONT(font,logFont);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteGdiInterop& WriteGdiInterop::CreateFontFaceFromHdc(HDC hdc,_Out_ IDWriteFontFace** fontFace)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateFontFaceFromHdc(hdc,fontFace);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteGdiInterop& WriteGdiInterop::CreateBitmapRenderTarget(_In_opt_ HDC hdc,UINT32 width,UINT32 height,_Out_ IDWriteBitmapRenderTarget** renderTarget)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateBitmapRenderTarget(hdc,width,height,renderTarget);
                CheckHRESULT(hr);
                return *this;
            }
            // ================================================================
            // WriteGlyphRunAnalysis
            // ================================================================
            HWIN_EXPORT WriteGlyphRunAnalysis& WriteGlyphRunAnalysis::GetAlphaTextureBounds(DWRITE_TEXTURE_TYPE textureType,_Out_ RECT* textureBounds)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetAlphaTextureBounds(textureType,textureBounds);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteGlyphRunAnalysis& WriteGlyphRunAnalysis::CreateAlphaTexture(DWRITE_TEXTURE_TYPE textureType,_In_ RECT const* textureBounds,BYTE* alphaValues, UINT32 bufferSize)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateAlphaTexture(textureType,textureBounds,alphaValues, bufferSize);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteGlyphRunAnalysis& WriteGlyphRunAnalysis::GetAlphaBlendParams(IDWriteRenderingParams* renderingParams,_Out_ FLOAT* blendGamma,_Out_ FLOAT* blendEnhancedContrast,_Out_ FLOAT* blendClearTypeLevel)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetAlphaBlendParams(renderingParams,blendGamma,blendEnhancedContrast,blendClearTypeLevel);
                CheckHRESULT(hr);
                return *this;
            }

            // ================================================================
            // WriteFactory
            // ================================================================
            HWIN_EXPORT WriteFactory::WriteFactory(DWRITE_FACTORY_TYPE factoryType)
            {
                IUnknown* factory = nullptr;
                HRESULT hr = DWriteCreateFactory(factoryType,__uuidof(IDWriteFactory),&factory);
                CheckHRESULT(hr);
                unknown = factory;
            }
                    
            HWIN_EXPORT WriteFactory& WriteFactory::GetSystemFontCollection(_Out_ IDWriteFontCollection** fontCollection, BOOL checkForUpdates )
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetSystemFontCollection(fontCollection, checkForUpdates );
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteFontCollection WriteFactory::GetSystemFontCollection(bool checkForUpdates )
            {
                IDWriteFontCollection* fontCollection = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetSystemFontCollection(&fontCollection, checkForUpdates );
                CheckHRESULT(hr);
                WriteFontCollection result(fontCollection);
                return result;
            }

            HWIN_EXPORT WriteFactory& WriteFactory::CreateCustomFontCollection( IDWriteFontCollectionLoader* collectionLoader, void const* collectionKey, UINT32 collectionKeySize, _Out_ IDWriteFontCollection** fontCollection)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateCustomFontCollection( collectionLoader, collectionKey, collectionKeySize, fontCollection);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteFontCollection WriteFactory::CreateCustomFontCollection( IDWriteFontCollectionLoader* collectionLoader, void const* collectionKey, UINT32 collectionKeySize)
            {
                IDWriteFontCollection* fontCollection = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateCustomFontCollection( collectionLoader, collectionKey, collectionKeySize, &fontCollection);
                CheckHRESULT(hr);
                WriteFontCollection result(fontCollection);
                return result;
            }

            HWIN_EXPORT WriteFactory& WriteFactory::RegisterFontCollectionLoader( IDWriteFontCollectionLoader* fontCollectionLoader)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->RegisterFontCollectionLoader(fontCollectionLoader);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteFactory& WriteFactory::UnregisterFontCollectionLoader(IDWriteFontCollectionLoader* fontCollectionLoader)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->UnregisterFontCollectionLoader(fontCollectionLoader);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteFactory& WriteFactory::CreateFontFileReference(_In_z_ WCHAR const* filePath,_In_opt_ FILETIME const* lastWriteTime,_Out_ IDWriteFontFile** fontFile)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateFontFileReference(filePath,lastWriteTime,fontFile);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteFontFile WriteFactory::CreateFontFileReference(_In_z_ WCHAR const* filePath,_In_opt_ FILETIME const* lastWriteTime )
            {
                IDWriteFontFile* fontFile = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateFontFileReference(filePath,lastWriteTime,&fontFile);
                CheckHRESULT(hr);
                WriteFontFile result(fontFile);
                return result;
            }
            HWIN_EXPORT WriteFactory& WriteFactory::CreateCustomFontFileReference(void const* fontFileReferenceKey, UINT32 fontFileReferenceKeySize, IDWriteFontFileLoader* fontFileLoader, _Out_ IDWriteFontFile** fontFile)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateCustomFontFileReference(fontFileReferenceKey, fontFileReferenceKeySize, fontFileLoader, fontFile);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteFontFile WriteFactory::CreateCustomFontFileReference(void const* fontFileReferenceKey, UINT32 fontFileReferenceKeySize, IDWriteFontFileLoader* fontFileLoader)
            {
                IDWriteFontFile* fontFile = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateCustomFontFileReference(fontFileReferenceKey, fontFileReferenceKeySize, fontFileLoader, &fontFile);
                CheckHRESULT(hr);
                WriteFontFile result(fontFile);
                return result;
            }

            HWIN_EXPORT WriteFactory& WriteFactory::CreateFontFace(DWRITE_FONT_FACE_TYPE fontFaceType,UINT32 numberOfFiles, IDWriteFontFile* const* fontFiles, UINT32 faceIndex, DWRITE_FONT_SIMULATIONS fontFaceSimulationFlags,_Out_ IDWriteFontFace** fontFace)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateFontFace(fontFaceType,numberOfFiles, fontFiles, faceIndex, fontFaceSimulationFlags,fontFace);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteFontFace WriteFactory::CreateFontFace(DWRITE_FONT_FACE_TYPE fontFaceType,UINT32 numberOfFiles, IDWriteFontFile* const* fontFiles, UINT32 faceIndex, DWRITE_FONT_SIMULATIONS fontFaceSimulationFlags)
            {
                IDWriteFontFace* fontFace = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateFontFace(fontFaceType,numberOfFiles, fontFiles, faceIndex, fontFaceSimulationFlags,&fontFace);
                CheckHRESULT(hr);
                WriteFontFace result(fontFace);
                return result;
            }

            HWIN_EXPORT WriteFactory& WriteFactory::CreateRenderingParams(_Out_ IDWriteRenderingParams** renderingParams)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateRenderingParams(renderingParams);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteRenderingParams WriteFactory::CreateRenderingParams( )
            {
                IDWriteRenderingParams* renderingParams = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateRenderingParams(&renderingParams);
                CheckHRESULT(hr);
                WriteRenderingParams result(renderingParams);
                return result;
            }

            HWIN_EXPORT WriteFactory& WriteFactory::CreateMonitorRenderingParams(HMONITOR monitor,_Out_ IDWriteRenderingParams** renderingParams)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateMonitorRenderingParams(monitor,renderingParams);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteRenderingParams WriteFactory::CreateMonitorRenderingParams(HMONITOR monitor)
            {
                IDWriteRenderingParams* renderingParams = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateMonitorRenderingParams(monitor,&renderingParams);
                CheckHRESULT(hr);
                WriteRenderingParams result(renderingParams);
                return result;
            }

            HWIN_EXPORT WriteFactory& WriteFactory::CreateCustomRenderingParams(FLOAT gamma,FLOAT enhancedContrast,FLOAT clearTypeLevel,DWRITE_PIXEL_GEOMETRY pixelGeometry,DWRITE_RENDERING_MODE renderingMode,_Out_ IDWriteRenderingParams** renderingParams)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateCustomRenderingParams(gamma,enhancedContrast,clearTypeLevel,pixelGeometry,renderingMode,renderingParams);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteRenderingParams WriteFactory::CreateCustomRenderingParams(FLOAT gamma,FLOAT enhancedContrast,FLOAT clearTypeLevel,DWRITE_PIXEL_GEOMETRY pixelGeometry,DWRITE_RENDERING_MODE renderingMode)
            {
                IDWriteRenderingParams* renderingParams = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateCustomRenderingParams(gamma,enhancedContrast,clearTypeLevel,pixelGeometry,renderingMode,&renderingParams);
                CheckHRESULT(hr);
                WriteRenderingParams result(renderingParams);
                return result;
            }

            HWIN_EXPORT WriteFactory& WriteFactory::RegisterFontFileLoader(IDWriteFontFileLoader* fontFileLoader)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->RegisterFontFileLoader(fontFileLoader);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteFactory& WriteFactory::UnregisterFontFileLoader(IDWriteFontFileLoader* fontFileLoader)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->UnregisterFontFileLoader(fontFileLoader);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteFactory& WriteFactory::CreateTextFormat(_In_z_ WCHAR const* fontFamilyName, _In_opt_ IDWriteFontCollection* fontCollection, DWRITE_FONT_WEIGHT fontWeight, DWRITE_FONT_STYLE fontStyle, DWRITE_FONT_STRETCH fontStretch, FLOAT fontSize,_In_z_ WCHAR const* localeName,_Out_ IDWriteTextFormat** textFormat)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateTextFormat(fontFamilyName, fontCollection, fontWeight, fontStyle, fontStretch, fontSize,localeName, textFormat);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteTextFormat WriteFactory::CreateTextFormat(_In_z_ WCHAR const* fontFamilyName, _In_opt_ IDWriteFontCollection* fontCollection, DWRITE_FONT_WEIGHT fontWeight, DWRITE_FONT_STYLE fontStyle, DWRITE_FONT_STRETCH fontStretch, FLOAT fontSize,_In_z_ WCHAR const* localeName)
            {
                IDWriteTextFormat* textFormat = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateTextFormat(fontFamilyName, fontCollection, fontWeight, fontStyle, fontStretch, fontSize,localeName, &textFormat);
                CheckHRESULT(hr);
                WriteTextFormat result(textFormat);
                return result;
            }

            HWIN_EXPORT WriteTextFormat WriteFactory::CreateTextFormat(_In_z_ WCHAR const* fontFamilyName, FLOAT fontSize)
            {
                wchar_t localeName[LOCALE_NAME_MAX_LENGTH+1] = {0,};
                LCIDToLocaleName(LOCALE_USER_DEFAULT,localeName,LOCALE_NAME_MAX_LENGTH,0);

                IDWriteTextFormat* textFormat = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateTextFormat(fontFamilyName, NULL, 
                                        DWRITE_FONT_WEIGHT_REGULAR, 
                                        DWRITE_FONT_STYLE_NORMAL, 
                                        DWRITE_FONT_STRETCH_NORMAL, 
                                        fontSize,
                                        localeName, 
                                        &textFormat);
                CheckHRESULT(hr);
                WriteTextFormat result(textFormat);
                return result;
            }


            HWIN_EXPORT WriteFactory& WriteFactory::CreateTypography(_Out_ IDWriteTypography** typography)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateTypography(typography);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteTypography WriteFactory::CreateTypography()
            {
                IDWriteTypography* typography = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateTypography(&typography);
                CheckHRESULT(hr);
                WriteTypography result(typography);
                return result;
            }

            HWIN_EXPORT WriteFactory& WriteFactory::GetGdiInterop(_Out_ IDWriteGdiInterop** gdiInterop)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetGdiInterop(gdiInterop);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteGdiInterop WriteFactory::GetGdiInterop()
            {
                IDWriteGdiInterop* gdiInterop = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->GetGdiInterop(&gdiInterop);
                CheckHRESULT(hr);
                WriteGdiInterop result(gdiInterop);
                return result;
            }

            HWIN_EXPORT WriteFactory& WriteFactory::CreateTextLayout(WCHAR const* string, UINT32 stringLength, IDWriteTextFormat* textFormat,FLOAT maxWidth, FLOAT maxHeight,_Out_ IDWriteTextLayout** textLayout)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateTextLayout(string, stringLength, textFormat,maxWidth, maxHeight,textLayout);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteTextLayout WriteFactory::CreateTextLayout(WCHAR const* string, UINT32 stringLength, IDWriteTextFormat* textFormat,FLOAT maxWidth, FLOAT maxHeight)
            {
                IDWriteTextLayout* textLayout = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateTextLayout(string, stringLength, textFormat,maxWidth, maxHeight,&textLayout);
                CheckHRESULT(hr);
                WriteTextLayout result(textLayout);
                return result;
            }

            HWIN_EXPORT WriteFactory& WriteFactory::CreateGdiCompatibleTextLayout(WCHAR const* string, UINT32 stringLength, IDWriteTextFormat* textFormat, FLOAT layoutWidth, FLOAT layoutHeight, FLOAT pixelsPerDip,_In_opt_ DWRITE_MATRIX const* transform, BOOL useGdiNatural, _Out_ IDWriteTextLayout** textLayout)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateGdiCompatibleTextLayout(string, stringLength, textFormat, layoutWidth, layoutHeight, pixelsPerDip,transform, useGdiNatural, textLayout);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteTextLayout WriteFactory::CreateGdiCompatibleTextLayout(WCHAR const* string, UINT32 stringLength, IDWriteTextFormat* textFormat, FLOAT layoutWidth, FLOAT layoutHeight, FLOAT pixelsPerDip,_In_opt_ DWRITE_MATRIX const* transform, BOOL useGdiNatural)
            {
                IDWriteTextLayout* textLayout = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateGdiCompatibleTextLayout(string, stringLength, textFormat, layoutWidth, layoutHeight, pixelsPerDip,transform, useGdiNatural, &textLayout);
                CheckHRESULT(hr);
                WriteTextLayout result(textLayout);
                return result;
            }

            HWIN_EXPORT WriteFactory& WriteFactory::CreateEllipsisTrimmingSign( IDWriteTextFormat* textFormat,_Out_ IDWriteInlineObject** trimmingSign)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateEllipsisTrimmingSign( textFormat,trimmingSign);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteInlineObject WriteFactory::CreateEllipsisTrimmingSign( IDWriteTextFormat* textFormat)
            {
                IDWriteInlineObject* trimmingSign = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateEllipsisTrimmingSign( textFormat,&trimmingSign);
                CheckHRESULT(hr);
                WriteInlineObject result(trimmingSign);
                return result;
            }
            HWIN_EXPORT WriteFactory& WriteFactory::CreateTextAnalyzer(_Out_ IDWriteTextAnalyzer** textAnalyzer)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateTextAnalyzer(textAnalyzer);
                CheckHRESULT(hr);
                return *this;
            }
            HWIN_EXPORT WriteTextAnalyzer WriteFactory::CreateTextAnalyzer( )
            {
                IDWriteTextAnalyzer* textAnalyzer = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateTextAnalyzer(&textAnalyzer);
                CheckHRESULT(hr);
                WriteTextAnalyzer result(textAnalyzer);
                return result;
            }

            HWIN_EXPORT WriteFactory& WriteFactory::CreateNumberSubstitution(_In_ DWRITE_NUMBER_SUBSTITUTION_METHOD substitutionMethod, _In_z_ WCHAR const* localeName, _In_ BOOL ignoreUserOverride, _Out_ IDWriteNumberSubstitution** numberSubstitution)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateNumberSubstitution(substitutionMethod, localeName, ignoreUserOverride, numberSubstitution);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteFactory& WriteFactory::CreateGlyphRunAnalysis(_In_ DWRITE_GLYPH_RUN const* glyphRun,FLOAT pixelsPerDip,_In_opt_ DWRITE_MATRIX const* transform, DWRITE_RENDERING_MODE renderingMode, DWRITE_MEASURING_MODE measuringMode, FLOAT baselineOriginX, FLOAT baselineOriginY, _Out_ IDWriteGlyphRunAnalysis** glyphRunAnalysis)
            {
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateGlyphRunAnalysis(glyphRun,pixelsPerDip,transform, renderingMode, measuringMode, baselineOriginX, baselineOriginY, glyphRunAnalysis);
                CheckHRESULT(hr);
                return *this;
            }

            HWIN_EXPORT WriteGlyphRunAnalysis WriteFactory::CreateGlyphRunAnalysis(_In_ DWRITE_GLYPH_RUN const* glyphRun,FLOAT pixelsPerDip,_In_opt_ DWRITE_MATRIX const* transform, DWRITE_RENDERING_MODE renderingMode, DWRITE_MEASURING_MODE measuringMode, FLOAT baselineOriginX, FLOAT baselineOriginY)
            {
                IDWriteGlyphRunAnalysis* glyphRunAnalysis = nullptr;
                InterfaceType* pInterface = GetInterface();
                HRESULT hr = pInterface->CreateGlyphRunAnalysis(glyphRun,pixelsPerDip,transform, renderingMode, measuringMode, baselineOriginX, baselineOriginY, &glyphRunAnalysis);
                CheckHRESULT(hr);
                WriteGlyphRunAnalysis result(glyphRunAnalysis);
                return result;
            }

            // ================================================================
            // 
            // ================================================================



        };
    };
};